Skip to content

Commit

Permalink
Merge tag 'block-6.5-2023-07-21' of git://git.kernel.dk/linux
Browse files Browse the repository at this point in the history
Pull block fixes from Jens Axboe:

 - Fix for loop regressions (Mauricio)

 - Fix a potential stall with batched wakeups in sbitmap (David)

 - Fix for stall with recursive plug flushes (Ross)

 - Skip accounting of empty requests for blk-iocost (Chengming)

 - Remove a dead field in struct blk_mq_hw_ctx (Chengming)

* tag 'block-6.5-2023-07-21' of git://git.kernel.dk/linux:
  loop: do not enforce max_loop hard limit by (new) default
  loop: deprecate autoloading callback loop_probe()
  sbitmap: fix batching wakeup
  blk-iocost: skip empty flush bio in iocost
  blk-mq: delete dead struct blk_mq_hw_ctx->queued field
  blk-mq: Fix stall due to recursive flush plug
  • Loading branch information
Linus Torvalds committed Jul 22, 2023
2 parents bdd1d82 + bb5faa9 commit f036d67
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 15 deletions.
3 changes: 1 addition & 2 deletions block/blk-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1144,8 +1144,7 @@ void __blk_flush_plug(struct blk_plug *plug, bool from_schedule)
{
if (!list_empty(&plug->cb_list))
flush_plug_callbacks(plug, from_schedule);
if (!rq_list_empty(plug->mq_list))
blk_mq_flush_plug_list(plug, from_schedule);
blk_mq_flush_plug_list(plug, from_schedule);
/*
* Unconditionally flush out cached requests, even if the unplug
* event came from schedule. Since we know hold references to the
Expand Down
4 changes: 4 additions & 0 deletions block/blk-iocost.c
Original file line number Diff line number Diff line change
Expand Up @@ -2516,6 +2516,10 @@ static void calc_vtime_cost_builtin(struct bio *bio, struct ioc_gq *iocg,
u64 seek_pages = 0;
u64 cost = 0;

/* Can't calculate cost for empty bio */
if (!bio->bi_iter.bi_size)
goto out;

switch (bio_op(bio)) {
case REQ_OP_READ:
coef_seqio = ioc->params.lcoefs[LCOEF_RSEQIO];
Expand Down
9 changes: 8 additions & 1 deletion block/blk-mq.c
Original file line number Diff line number Diff line change
Expand Up @@ -2754,7 +2754,14 @@ void blk_mq_flush_plug_list(struct blk_plug *plug, bool from_schedule)
{
struct request *rq;

if (rq_list_empty(plug->mq_list))
/*
* We may have been called recursively midway through handling
* plug->mq_list via a schedule() in the driver's queue_rq() callback.
* To avoid mq_list changing under our feet, clear rq_count early and
* bail out specifically if rq_count is 0 rather than checking
* whether the mq_list is empty.
*/
if (plug->rq_count == 0)
return;
plug->rq_count = 0;

Expand Down
40 changes: 38 additions & 2 deletions drivers/block/loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -1775,14 +1775,43 @@ static const struct block_device_operations lo_fops = {
/*
* If max_loop is specified, create that many devices upfront.
* This also becomes a hard limit. If max_loop is not specified,
* the default isn't a hard limit (as before commit 85c50197716c
* changed the default value from 0 for max_loop=0 reasons), just
* create CONFIG_BLK_DEV_LOOP_MIN_COUNT loop devices at module
* init time. Loop devices can be requested on-demand with the
* /dev/loop-control interface, or be instantiated by accessing
* a 'dead' device node.
*/
static int max_loop = CONFIG_BLK_DEV_LOOP_MIN_COUNT;
module_param(max_loop, int, 0444);

#ifdef CONFIG_BLOCK_LEGACY_AUTOLOAD
static bool max_loop_specified;

static int max_loop_param_set_int(const char *val,
const struct kernel_param *kp)
{
int ret;

ret = param_set_int(val, kp);
if (ret < 0)
return ret;

max_loop_specified = true;
return 0;
}

static const struct kernel_param_ops max_loop_param_ops = {
.set = max_loop_param_set_int,
.get = param_get_int,
};

module_param_cb(max_loop, &max_loop_param_ops, &max_loop, 0444);
MODULE_PARM_DESC(max_loop, "Maximum number of loop devices");
#else
module_param(max_loop, int, 0444);
MODULE_PARM_DESC(max_loop, "Initial number of loop devices");
#endif

module_param(max_part, int, 0444);
MODULE_PARM_DESC(max_part, "Maximum number of partitions per loop device");

Expand Down Expand Up @@ -2093,14 +2122,18 @@ static void loop_remove(struct loop_device *lo)
put_disk(lo->lo_disk);
}

#ifdef CONFIG_BLOCK_LEGACY_AUTOLOAD
static void loop_probe(dev_t dev)
{
int idx = MINOR(dev) >> part_shift;

if (max_loop && idx >= max_loop)
if (max_loop_specified && max_loop && idx >= max_loop)
return;
loop_add(idx);
}
#else
#define loop_probe NULL
#endif /* !CONFIG_BLOCK_LEGACY_AUTOLOAD */

static int loop_control_remove(int idx)
{
Expand Down Expand Up @@ -2281,6 +2314,9 @@ module_exit(loop_exit);
static int __init max_loop_setup(char *str)
{
max_loop = simple_strtol(str, NULL, 0);
#ifdef CONFIG_BLOCK_LEGACY_AUTOLOAD
max_loop_specified = true;
#endif
return 1;
}

Expand Down
2 changes: 0 additions & 2 deletions include/linux/blk-mq.h
Original file line number Diff line number Diff line change
Expand Up @@ -397,8 +397,6 @@ struct blk_mq_hw_ctx {
*/
struct blk_mq_tags *sched_tags;

/** @queued: Number of queued requests. */
unsigned long queued;
/** @run: Number of dispatched requests. */
unsigned long run;

Expand Down
15 changes: 7 additions & 8 deletions lib/sbitmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ EXPORT_SYMBOL_GPL(sbitmap_queue_min_shallow_depth);

static void __sbitmap_queue_wake_up(struct sbitmap_queue *sbq, int nr)
{
int i, wake_index;
int i, wake_index, woken;

if (!atomic_read(&sbq->ws_active))
return;
Expand All @@ -567,13 +567,12 @@ static void __sbitmap_queue_wake_up(struct sbitmap_queue *sbq, int nr)
*/
wake_index = sbq_index_inc(wake_index);

/*
* It is sufficient to wake up at least one waiter to
* guarantee forward progress.
*/
if (waitqueue_active(&ws->wait) &&
wake_up_nr(&ws->wait, nr))
break;
if (waitqueue_active(&ws->wait)) {
woken = wake_up_nr(&ws->wait, nr);
if (woken == nr)
break;
nr -= woken;
}
}

if (wake_index != atomic_read(&sbq->wake_index))
Expand Down

0 comments on commit f036d67

Please sign in to comment.