Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.dk/linux-block
Browse files Browse the repository at this point in the history
Pull block bits from Jens Axboe:
 "As vacation is coming up, thought I'd better get rid of my pending
  changes in my for-linus branch for this iteration.  It contains:

   - Two patches for mtip32xx.  Killing a non-compliant sysfs interface
     and moving it to debugfs, where it belongs.

   - A few patches from Asias.  Two legit bug fixes, and one killing an
     interface that is no longer in use.

   - A patch from Jan, making the annoying partition ioctl warning a bit
     less annoying, by restricting it to !CAP_SYS_RAWIO only.

   - Three bug fixes for drbd from Lars Ellenberg.

   - A fix for an old regression for umem, it hasn't really worked since
     the plugging scheme was changed in 3.0.

   - A few fixes from Tejun.

   - A splice fix from Eric Dumazet, fixing an issue with pipe
     resizing."

* 'for-linus' of git://git.kernel.dk/linux-block:
  scsi: Silence unnecessary warnings about ioctl to partition
  block: Drop dead function blk_abort_queue()
  block: Mitigate lock unbalance caused by lock switching
  block: Avoid missed wakeup in request waitqueue
  umem: fix up unplugging
  splice: fix racy pipe->buffers uses
  drbd: fix null pointer dereference with on-congestion policy when diskless
  drbd: fix list corruption by failing but already aborted reads
  drbd: fix access of unallocated pages and kernel panic
  xen/blkfront: Add WARN to deal with misbehaving backends.
  blkcg: drop local variable @q from blkg_destroy()
  mtip32xx: Create debugfs entries for troubleshooting
  mtip32xx: Remove 'registers' and 'flags' from sysfs
  blkcg: fix blkg_alloc() failure path
  block: blkcg_policy_cfq shouldn't be used if !CONFIG_CFQ_GROUP_IOSCHED
  block: fix return value on cfq_init() failure
  mtip32xx: Remove version.h header file inclusion
  xen/blkback: Copy id field when doing BLKIF_DISCARD.
  • Loading branch information
torvalds committed Jul 3, 2012
2 parents ff826b2 + 6d93592 commit a3da2c6
Show file tree
Hide file tree
Showing 20 changed files with 338 additions and 200 deletions.
21 changes: 0 additions & 21 deletions Documentation/ABI/testing/sysfs-block-rssd
Original file line number Diff line number Diff line change
@@ -1,26 +1,5 @@
What: /sys/block/rssd*/registers
Date: March 2012
KernelVersion: 3.3
Contact: Asai Thambi S P <[email protected]>
Description: This is a read-only file. Dumps below driver information and
hardware registers.
- S ACTive
- Command Issue
- Completed
- PORT IRQ STAT
- HOST IRQ STAT
- Allocated
- Commands in Q

What: /sys/block/rssd*/status
Date: April 2012
KernelVersion: 3.4
Contact: Asai Thambi S P <[email protected]>
Description: This is a read-only file. Indicates the status of the device.

What: /sys/block/rssd*/flags
Date: May 2012
KernelVersion: 3.5
Contact: Asai Thambi S P <[email protected]>
Description: This is a read-only file. Dumps the flags in port and driver
data structure
9 changes: 2 additions & 7 deletions block/blk-cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,8 @@ static struct blkcg_gq *blkg_alloc(struct blkcg *blkcg, struct request_queue *q)

blkg->pd[i] = pd;
pd->blkg = blkg;
}

/* invoke per-policy init */
for (i = 0; i < BLKCG_MAX_POLS; i++) {
struct blkcg_policy *pol = blkcg_policy[i];

/* invoke per-policy init */
if (blkcg_policy_enabled(blkg->q, pol))
pol->pd_init_fn(blkg);
}
Expand Down Expand Up @@ -245,10 +241,9 @@ EXPORT_SYMBOL_GPL(blkg_lookup_create);

static void blkg_destroy(struct blkcg_gq *blkg)
{
struct request_queue *q = blkg->q;
struct blkcg *blkcg = blkg->blkcg;

lockdep_assert_held(q->queue_lock);
lockdep_assert_held(blkg->q->queue_lock);
lockdep_assert_held(&blkcg->lock);

/* Something wrong if we are trying to remove same group twice */
Expand Down
25 changes: 19 additions & 6 deletions block/blk-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,9 +361,10 @@ EXPORT_SYMBOL(blk_put_queue);
*/
void blk_drain_queue(struct request_queue *q, bool drain_all)
{
int i;

while (true) {
bool drain = false;
int i;

spin_lock_irq(q->queue_lock);

Expand Down Expand Up @@ -408,6 +409,18 @@ void blk_drain_queue(struct request_queue *q, bool drain_all)
break;
msleep(10);
}

/*
* With queue marked dead, any woken up waiter will fail the
* allocation path, so the wakeup chaining is lost and we're
* left with hung waiters. We need to wake up those waiters.
*/
if (q->request_fn) {
spin_lock_irq(q->queue_lock);
for (i = 0; i < ARRAY_SIZE(q->rq.wait); i++)
wake_up_all(&q->rq.wait[i]);
spin_unlock_irq(q->queue_lock);
}
}

/**
Expand Down Expand Up @@ -467,7 +480,6 @@ void blk_cleanup_queue(struct request_queue *q)
/* mark @q DEAD, no new request or merges will be allowed afterwards */
mutex_lock(&q->sysfs_lock);
queue_flag_set_unlocked(QUEUE_FLAG_DEAD, q);

spin_lock_irq(lock);

/*
Expand All @@ -485,10 +497,6 @@ void blk_cleanup_queue(struct request_queue *q)
queue_flag_set(QUEUE_FLAG_NOMERGES, q);
queue_flag_set(QUEUE_FLAG_NOXMERGES, q);
queue_flag_set(QUEUE_FLAG_DEAD, q);

if (q->queue_lock != &q->__queue_lock)
q->queue_lock = &q->__queue_lock;

spin_unlock_irq(lock);
mutex_unlock(&q->sysfs_lock);

Expand All @@ -499,6 +507,11 @@ void blk_cleanup_queue(struct request_queue *q)
del_timer_sync(&q->backing_dev_info.laptop_mode_wb_timer);
blk_sync_queue(q);

spin_lock_irq(lock);
if (q->queue_lock != &q->__queue_lock)
q->queue_lock = &q->__queue_lock;
spin_unlock_irq(lock);

/* @q is and will stay empty, shutdown and put */
blk_put_queue(q);
}
Expand Down
41 changes: 0 additions & 41 deletions block/blk-timeout.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,44 +197,3 @@ void blk_add_timer(struct request *req)
mod_timer(&q->timeout, expiry);
}

/**
* blk_abort_queue -- Abort all request on given queue
* @queue: pointer to queue
*
*/
void blk_abort_queue(struct request_queue *q)
{
unsigned long flags;
struct request *rq, *tmp;
LIST_HEAD(list);

/*
* Not a request based block device, nothing to abort
*/
if (!q->request_fn)
return;

spin_lock_irqsave(q->queue_lock, flags);

elv_abort_queue(q);

/*
* Splice entries to local list, to avoid deadlocking if entries
* get readded to the timeout list by error handling
*/
list_splice_init(&q->timeout_list, &list);

list_for_each_entry_safe(rq, tmp, &list, timeout_list)
blk_abort_request(rq);

/*
* Occasionally, blk_abort_request() will return without
* deleting the element from the list. Make sure we add those back
* instead of leaving them on the local stack list.
*/
list_splice(&list, &q->timeout_list);

spin_unlock_irqrestore(q->queue_lock, flags);

}
EXPORT_SYMBOL_GPL(blk_abort_queue);
30 changes: 18 additions & 12 deletions block/cfq-iosched.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
#include "blk.h"
#include "blk-cgroup.h"

static struct blkcg_policy blkcg_policy_cfq __maybe_unused;

/*
* tunables
*/
Expand Down Expand Up @@ -418,11 +416,6 @@ static inline struct cfq_group *pd_to_cfqg(struct blkg_policy_data *pd)
return pd ? container_of(pd, struct cfq_group, pd) : NULL;
}

static inline struct cfq_group *blkg_to_cfqg(struct blkcg_gq *blkg)
{
return pd_to_cfqg(blkg_to_pd(blkg, &blkcg_policy_cfq));
}

static inline struct blkcg_gq *cfqg_to_blkg(struct cfq_group *cfqg)
{
return pd_to_blkg(&cfqg->pd);
Expand Down Expand Up @@ -572,6 +565,13 @@ static inline void cfqg_stats_update_avg_queue_size(struct cfq_group *cfqg) { }

#ifdef CONFIG_CFQ_GROUP_IOSCHED

static struct blkcg_policy blkcg_policy_cfq;

static inline struct cfq_group *blkg_to_cfqg(struct blkcg_gq *blkg)
{
return pd_to_cfqg(blkg_to_pd(blkg, &blkcg_policy_cfq));
}

static inline void cfqg_get(struct cfq_group *cfqg)
{
return blkg_get(cfqg_to_blkg(cfqg));
Expand Down Expand Up @@ -3951,10 +3951,11 @@ static void cfq_exit_queue(struct elevator_queue *e)

cfq_shutdown_timer_wq(cfqd);

#ifndef CONFIG_CFQ_GROUP_IOSCHED
#ifdef CONFIG_CFQ_GROUP_IOSCHED
blkcg_deactivate_policy(q, &blkcg_policy_cfq);
#else
kfree(cfqd->root_group);
#endif
blkcg_deactivate_policy(q, &blkcg_policy_cfq);
kfree(cfqd);
}

Expand Down Expand Up @@ -4194,14 +4195,15 @@ static int __init cfq_init(void)
#ifdef CONFIG_CFQ_GROUP_IOSCHED
if (!cfq_group_idle)
cfq_group_idle = 1;
#else
cfq_group_idle = 0;
#endif

ret = blkcg_policy_register(&blkcg_policy_cfq);
if (ret)
return ret;
#else
cfq_group_idle = 0;
#endif

ret = -ENOMEM;
cfq_pool = KMEM_CACHE(cfq_queue, 0);
if (!cfq_pool)
goto err_pol_unreg;
Expand All @@ -4215,13 +4217,17 @@ static int __init cfq_init(void)
err_free_pool:
kmem_cache_destroy(cfq_pool);
err_pol_unreg:
#ifdef CONFIG_CFQ_GROUP_IOSCHED
blkcg_policy_unregister(&blkcg_policy_cfq);
#endif
return ret;
}

static void __exit cfq_exit(void)
{
#ifdef CONFIG_CFQ_GROUP_IOSCHED
blkcg_policy_unregister(&blkcg_policy_cfq);
#endif
elv_unregister(&iosched_cfq);
kmem_cache_destroy(cfq_pool);
}
Expand Down
5 changes: 4 additions & 1 deletion block/scsi_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -721,11 +721,14 @@ int scsi_verify_blk_ioctl(struct block_device *bd, unsigned int cmd)
break;
}

if (capable(CAP_SYS_RAWIO))
return 0;

/* In particular, rule out all resets and host-specific ioctls. */
printk_ratelimited(KERN_WARNING
"%s: sending ioctl %x to a partition!\n", current->comm, cmd);

return capable(CAP_SYS_RAWIO) ? 0 : -ENOIOCTLCMD;
return -ENOIOCTLCMD;
}
EXPORT_SYMBOL(scsi_verify_blk_ioctl);

Expand Down
11 changes: 9 additions & 2 deletions drivers/block/drbd/drbd_bitmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1475,10 +1475,17 @@ void _drbd_bm_set_bits(struct drbd_conf *mdev, const unsigned long s, const unsi
first_word = 0;
spin_lock_irq(&b->bm_lock);
}

/* last page (respectively only page, for first page == last page) */
last_word = MLPP(el >> LN2_BPL);
bm_set_full_words_within_one_page(mdev->bitmap, last_page, first_word, last_word);

/* consider bitmap->bm_bits = 32768, bitmap->bm_number_of_pages = 1. (or multiples).
* ==> e = 32767, el = 32768, last_page = 2,
* and now last_word = 0.
* We do not want to touch last_page in this case,
* as we did not allocate it, it is not present in bitmap->bm_pages.
*/
if (last_word)
bm_set_full_words_within_one_page(mdev->bitmap, last_page, first_word, last_word);

/* possibly trailing bits.
* example: (e & 63) == 63, el will be e+1.
Expand Down
66 changes: 42 additions & 24 deletions drivers/block/drbd/drbd_req.c
Original file line number Diff line number Diff line change
Expand Up @@ -472,12 +472,17 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
req->rq_state |= RQ_LOCAL_COMPLETED;
req->rq_state &= ~RQ_LOCAL_PENDING;

D_ASSERT(!(req->rq_state & RQ_NET_MASK));
if (req->rq_state & RQ_LOCAL_ABORTED) {
_req_may_be_done(req, m);
break;
}

__drbd_chk_io_error(mdev, false);

goto_queue_for_net_read:

D_ASSERT(!(req->rq_state & RQ_NET_MASK));

/* no point in retrying if there is no good remote data,
* or we have no connection. */
if (mdev->state.pdsk != D_UP_TO_DATE) {
Expand Down Expand Up @@ -765,6 +770,40 @@ static int drbd_may_do_local_read(struct drbd_conf *mdev, sector_t sector, int s
return 0 == drbd_bm_count_bits(mdev, sbnr, ebnr);
}

static void maybe_pull_ahead(struct drbd_conf *mdev)
{
int congested = 0;

/* If I don't even have good local storage, we can not reasonably try
* to pull ahead of the peer. We also need the local reference to make
* sure mdev->act_log is there.
* Note: caller has to make sure that net_conf is there.
*/
if (!get_ldev_if_state(mdev, D_UP_TO_DATE))
return;

if (mdev->net_conf->cong_fill &&
atomic_read(&mdev->ap_in_flight) >= mdev->net_conf->cong_fill) {
dev_info(DEV, "Congestion-fill threshold reached\n");
congested = 1;
}

if (mdev->act_log->used >= mdev->net_conf->cong_extents) {
dev_info(DEV, "Congestion-extents threshold reached\n");
congested = 1;
}

if (congested) {
queue_barrier(mdev); /* last barrier, after mirrored writes */

if (mdev->net_conf->on_congestion == OC_PULL_AHEAD)
_drbd_set_state(_NS(mdev, conn, C_AHEAD), 0, NULL);
else /*mdev->net_conf->on_congestion == OC_DISCONNECT */
_drbd_set_state(_NS(mdev, conn, C_DISCONNECTING), 0, NULL);
}
put_ldev(mdev);
}

static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, unsigned long start_time)
{
const int rw = bio_rw(bio);
Expand Down Expand Up @@ -972,29 +1011,8 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, uns
_req_mod(req, queue_for_send_oos);

if (remote &&
mdev->net_conf->on_congestion != OC_BLOCK && mdev->agreed_pro_version >= 96) {
int congested = 0;

if (mdev->net_conf->cong_fill &&
atomic_read(&mdev->ap_in_flight) >= mdev->net_conf->cong_fill) {
dev_info(DEV, "Congestion-fill threshold reached\n");
congested = 1;
}

if (mdev->act_log->used >= mdev->net_conf->cong_extents) {
dev_info(DEV, "Congestion-extents threshold reached\n");
congested = 1;
}

if (congested) {
queue_barrier(mdev); /* last barrier, after mirrored writes */

if (mdev->net_conf->on_congestion == OC_PULL_AHEAD)
_drbd_set_state(_NS(mdev, conn, C_AHEAD), 0, NULL);
else /*mdev->net_conf->on_congestion == OC_DISCONNECT */
_drbd_set_state(_NS(mdev, conn, C_DISCONNECTING), 0, NULL);
}
}
mdev->net_conf->on_congestion != OC_BLOCK && mdev->agreed_pro_version >= 96)
maybe_pull_ahead(mdev);

spin_unlock_irq(&mdev->req_lock);
kfree(b); /* if someone else has beaten us to it... */
Expand Down
Loading

0 comments on commit a3da2c6

Please sign in to comment.