Skip to content

Commit

Permalink
Merge tag 'for-5.7/block-2020-03-29' of git://git.kernel.dk/linux-block
Browse files Browse the repository at this point in the history
Pull block updates from Jens Axboe:

 - Online capacity resizing (Balbir)

 - Number of hardware queue change fixes (Bart)

 - null_blk fault injection addition (Bart)

 - Cleanup of queue allocation, unifying the node/no-node API
   (Christoph)

 - Cleanup of genhd, moving code to where it makes sense (Christoph)

 - Cleanup of the partition handling code (Christoph)

 - disk stat fixes/improvements (Konstantin)

 - BFQ improvements (Paolo)

 - Various fixes and improvements

* tag 'for-5.7/block-2020-03-29' of git://git.kernel.dk/linux-block: (72 commits)
  block: return NULL in blk_alloc_queue() on error
  block: move bio_map_* to blk-map.c
  Revert "blkdev: check for valid request queue before issuing flush"
  block: simplify queue allocation
  bcache: pass the make_request methods to blk_queue_make_request
  null_blk: use blk_mq_init_queue_data
  block: add a blk_mq_init_queue_data helper
  block: move the ->devnode callback to struct block_device_operations
  block: move the part_stat* helpers from genhd.h to a new header
  block: move block layer internals out of include/linux/genhd.h
  block: move guard_bio_eod to bio.c
  block: unexport get_gendisk
  block: unexport disk_map_sector_rcu
  block: unexport disk_get_part
  block: mark part_in_flight and part_in_flight_rw static
  block: mark block_depr static
  block: factor out requeue handling from dispatch code
  block/diskstats: replace time_in_queue with sum of request times
  block/diskstats: accumulate all per-cpu counters in one pass
  block/diskstats: more accurate approximation of io_ticks for slow disks
  ...
  • Loading branch information
torvalds committed Mar 30, 2020
2 parents 3a0eb19 + 654a366 commit 10f36b1
Show file tree
Hide file tree
Showing 111 changed files with 1,950 additions and 2,039 deletions.
5 changes: 4 additions & 1 deletion Documentation/admin-guide/iostats.rst
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ Field 10 -- # of milliseconds spent doing I/Os (unsigned int)

Since 5.0 this field counts jiffies when at least one request was
started or completed. If request runs more than 2 jiffies then some
I/O time will not be accounted unless there are other requests.
I/O time might be not accounted in case of concurrent requests.

Field 11 -- weighted # of milliseconds spent doing I/Os (unsigned int)
This field is incremented at each I/O start, I/O completion, I/O
Expand Down Expand Up @@ -143,6 +143,9 @@ are summed (possibly overflowing the unsigned long variable they are
summed to) and the result given to the user. There is no convenient
user interface for accessing the per-CPU counters themselves.

Since 4.19 request times are measured with nanoseconds precision and
truncated to milliseconds before showing in this interface.

Disks vs Partitions
-------------------

Expand Down
16 changes: 4 additions & 12 deletions Documentation/block/capability.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,9 @@
Generic Block Device Capability
===============================

This file documents the sysfs file block/<disk>/capability
This file documents the sysfs file ``block/<disk>/capability``.

capability is a hex word indicating which capabilities a specific disk
supports. For more information on bits not listed here, see
include/linux/genhd.h
``capability`` is a bitfield, printed in hexadecimal, indicating which
capabilities a specific block device supports:

GENHD_FL_MEDIA_CHANGE_NOTIFY
----------------------------

Value: 4

When this bit is set, the disk supports Asynchronous Notification
of media change events. These events will be broadcast to user
space via kernel uevent.
.. kernel-doc:: include/linux/genhd.h
21 changes: 0 additions & 21 deletions Documentation/scsi/scsi_mid_low_api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,6 @@ Summary:
scsi_host_alloc - return a new scsi_host instance whose refcount==1
scsi_host_get - increments Scsi_Host instance's refcount
scsi_host_put - decrements Scsi_Host instance's refcount (free if 0)
scsi_partsize - parse partition table into cylinders, heads + sectors
scsi_register - create and register a scsi host adapter instance.
scsi_remove_device - detach and remove a SCSI device
scsi_remove_host - detach and remove all SCSI devices owned by host
Expand Down Expand Up @@ -472,26 +471,6 @@ void scsi_host_get(struct Scsi_Host *shost)
void scsi_host_put(struct Scsi_Host *shost)


/**
* scsi_partsize - parse partition table into cylinders, heads + sectors
* @buf: pointer to partition table
* @capacity: size of (total) disk in 512 byte sectors
* @cyls: outputs number of cylinders calculated via this pointer
* @hds: outputs number of heads calculated via this pointer
* @secs: outputs number of sectors calculated via this pointer
*
* Returns 0 on success, -1 on failure
*
* Might block: no
*
* Notes: Caller owns memory returned (free with kfree() )
*
* Defined in: drivers/scsi/scsicam.c
**/
int scsi_partsize(unsigned char *buf, unsigned long capacity,
unsigned int *cyls, unsigned int *hds, unsigned int *secs)


/**
* scsi_register - create and register a scsi host adapter instance.
* @sht: pointer to scsi host template
Expand Down
3 changes: 1 addition & 2 deletions arch/m68k/emu/nfblock.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,11 @@ static int __init nfhd_init_one(int id, u32 blocks, u32 bsize)
dev->bsize = bsize;
dev->bshift = ffs(bsize) - 10;

dev->queue = blk_alloc_queue(GFP_KERNEL);
dev->queue = blk_alloc_queue(nfhd_make_request, NUMA_NO_NODE);
if (dev->queue == NULL)
goto free_dev;

dev->queue->queuedata = dev;
blk_queue_make_request(dev->queue, nfhd_make_request);
blk_queue_logical_block_size(dev->queue, bsize);

dev->disk = alloc_disk(16);
Expand Down
3 changes: 1 addition & 2 deletions arch/xtensa/platforms/iss/simdisk.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,13 +267,12 @@ static int __init simdisk_setup(struct simdisk *dev, int which,
spin_lock_init(&dev->lock);
dev->users = 0;

dev->queue = blk_alloc_queue(GFP_KERNEL);
dev->queue = blk_alloc_queue(simdisk_make_request, NUMA_NO_NODE);
if (dev->queue == NULL) {
pr_err("blk_alloc_queue failed\n");
goto out_alloc_queue;
}

blk_queue_make_request(dev->queue, simdisk_make_request);
dev->queue->queuedata = dev;

dev->gd = alloc_disk(SIMDISK_MINORS);
Expand Down
3 changes: 1 addition & 2 deletions block/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ obj-$(CONFIG_BLOCK) := bio.o elevator.o blk-core.o blk-sysfs.o \
blk-exec.o blk-merge.o blk-softirq.o blk-timeout.o \
blk-lib.o blk-mq.o blk-mq-tag.o blk-stat.o \
blk-mq-sysfs.o blk-mq-cpumap.o blk-mq-sched.o ioctl.o \
genhd.o partition-generic.o ioprio.o \
badblocks.o partitions/ blk-rq-qos.o
genhd.o ioprio.o badblocks.o partitions/ blk-rq-qos.o

obj-$(CONFIG_BOUNCE) += bounce.o
obj-$(CONFIG_BLK_SCSI_REQUEST) += scsi_ioctl.o
Expand Down
87 changes: 52 additions & 35 deletions block/bfq-cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,12 @@ void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,
{
struct bfq_entity *entity = &bfqq->entity;

/*
* Get extra reference to prevent bfqq from being freed in
* next possible expire or deactivate.
*/
bfqq->ref++;

/* If bfqq is empty, then bfq_bfqq_expire also invokes
* bfq_del_bfqq_busy, thereby removing bfqq and its entity
* from data structures related to current group. Otherwise we
Expand All @@ -652,12 +658,6 @@ void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,
bfq_bfqq_expire(bfqd, bfqd->in_service_queue,
false, BFQQE_PREEMPTED);

/*
* get extra reference to prevent bfqq from being freed in
* next possible deactivate
*/
bfqq->ref++;

if (bfq_bfqq_busy(bfqq))
bfq_deactivate_bfqq(bfqd, bfqq, false, false);
else if (entity->on_st_or_in_serv)
Expand All @@ -677,7 +677,7 @@ void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,

if (!bfqd->in_service_queue && !bfqd->rq_in_driver)
bfq_schedule_dispatch(bfqd);
/* release extra ref taken above */
/* release extra ref taken above, bfqq may happen to be freed now */
bfq_put_queue(bfqq);
}

Expand Down Expand Up @@ -714,10 +714,7 @@ static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd,

if (entity->sched_data != &bfqg->sched_data) {
bic_set_bfqq(bic, NULL, 0);
bfq_log_bfqq(bfqd, async_bfqq,
"bic_change_group: %p %d",
async_bfqq, async_bfqq->ref);
bfq_put_queue(async_bfqq);
bfq_release_process_ref(bfqd, async_bfqq);
}
}

Expand Down Expand Up @@ -818,39 +815,53 @@ static void bfq_flush_idle_tree(struct bfq_service_tree *st)
/**
* bfq_reparent_leaf_entity - move leaf entity to the root_group.
* @bfqd: the device data structure with the root group.
* @entity: the entity to move.
* @entity: the entity to move, if entity is a leaf; or the parent entity
* of an active leaf entity to move, if entity is not a leaf.
*/
static void bfq_reparent_leaf_entity(struct bfq_data *bfqd,
struct bfq_entity *entity)
struct bfq_entity *entity,
int ioprio_class)
{
struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
struct bfq_queue *bfqq;
struct bfq_entity *child_entity = entity;

while (child_entity->my_sched_data) { /* leaf not reached yet */
struct bfq_sched_data *child_sd = child_entity->my_sched_data;
struct bfq_service_tree *child_st = child_sd->service_tree +
ioprio_class;
struct rb_root *child_active = &child_st->active;

child_entity = bfq_entity_of(rb_first(child_active));

if (!child_entity)
child_entity = child_sd->in_service_entity;
}

bfqq = bfq_entity_to_bfqq(child_entity);
bfq_bfqq_move(bfqd, bfqq, bfqd->root_group);
}

/**
* bfq_reparent_active_entities - move to the root group all active
* entities.
* bfq_reparent_active_queues - move to the root group all active queues.
* @bfqd: the device data structure with the root group.
* @bfqg: the group to move from.
* @st: the service tree with the entities.
* @st: the service tree to start the search from.
*/
static void bfq_reparent_active_entities(struct bfq_data *bfqd,
struct bfq_group *bfqg,
struct bfq_service_tree *st)
static void bfq_reparent_active_queues(struct bfq_data *bfqd,
struct bfq_group *bfqg,
struct bfq_service_tree *st,
int ioprio_class)
{
struct rb_root *active = &st->active;
struct bfq_entity *entity = NULL;

if (!RB_EMPTY_ROOT(&st->active))
entity = bfq_entity_of(rb_first(active));
struct bfq_entity *entity;

for (; entity ; entity = bfq_entity_of(rb_first(active)))
bfq_reparent_leaf_entity(bfqd, entity);
while ((entity = bfq_entity_of(rb_first(active))))
bfq_reparent_leaf_entity(bfqd, entity, ioprio_class);

if (bfqg->sched_data.in_service_entity)
bfq_reparent_leaf_entity(bfqd,
bfqg->sched_data.in_service_entity);
bfqg->sched_data.in_service_entity,
ioprio_class);
}

/**
Expand Down Expand Up @@ -882,13 +893,6 @@ static void bfq_pd_offline(struct blkg_policy_data *pd)
for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) {
st = bfqg->sched_data.service_tree + i;

/*
* The idle tree may still contain bfq_queues belonging
* to exited task because they never migrated to a different
* cgroup from the one being destroyed now.
*/
bfq_flush_idle_tree(st);

/*
* It may happen that some queues are still active
* (busy) upon group destruction (if the corresponding
Expand All @@ -901,7 +905,20 @@ static void bfq_pd_offline(struct blkg_policy_data *pd)
* There is no need to put the sync queues, as the
* scheduler has taken no reference.
*/
bfq_reparent_active_entities(bfqd, bfqg, st);
bfq_reparent_active_queues(bfqd, bfqg, st, i);

/*
* The idle tree may still contain bfq_queues
* belonging to exited task because they never
* migrated to a different cgroup from the one being
* destroyed now. In addition, even
* bfq_reparent_active_queues() may happen to add some
* entities to the idle tree. It happens if, in some
* of the calls to bfq_bfqq_move() performed by
* bfq_reparent_active_queues(), the queue to move is
* empty and gets expired.
*/
bfq_flush_idle_tree(st);
}

__bfq_deactivate_entity(entity, false);
Expand Down
18 changes: 12 additions & 6 deletions block/bfq-iosched.c
Original file line number Diff line number Diff line change
Expand Up @@ -2716,8 +2716,6 @@ static void bfq_bfqq_save_state(struct bfq_queue *bfqq)
}
}


static
void bfq_release_process_ref(struct bfq_data *bfqd, struct bfq_queue *bfqq)
{
/*
Expand Down Expand Up @@ -6215,20 +6213,28 @@ static struct bfq_queue *bfq_init_rq(struct request *rq)
return bfqq;
}

static void bfq_idle_slice_timer_body(struct bfq_queue *bfqq)
static void
bfq_idle_slice_timer_body(struct bfq_data *bfqd, struct bfq_queue *bfqq)
{
struct bfq_data *bfqd = bfqq->bfqd;
enum bfqq_expiration reason;
unsigned long flags;

spin_lock_irqsave(&bfqd->lock, flags);
bfq_clear_bfqq_wait_request(bfqq);

/*
* Considering that bfqq may be in race, we should firstly check
* whether bfqq is in service before doing something on it. If
* the bfqq in race is not in service, it has already been expired
* through __bfq_bfqq_expire func and its wait_request flags has
* been cleared in __bfq_bfqd_reset_in_service func.
*/
if (bfqq != bfqd->in_service_queue) {
spin_unlock_irqrestore(&bfqd->lock, flags);
return;
}

bfq_clear_bfqq_wait_request(bfqq);

if (bfq_bfqq_budget_timeout(bfqq))
/*
* Also here the queue can be safely expired
Expand Down Expand Up @@ -6273,7 +6279,7 @@ static enum hrtimer_restart bfq_idle_slice_timer(struct hrtimer *timer)
* early.
*/
if (bfqq)
bfq_idle_slice_timer_body(bfqq);
bfq_idle_slice_timer_body(bfqd, bfqq);

return HRTIMER_NORESTART;
}
Expand Down
1 change: 1 addition & 0 deletions block/bfq-iosched.h
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,7 @@ void bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq,
bool compensate, enum bfqq_expiration reason);
void bfq_put_queue(struct bfq_queue *bfqq);
void bfq_end_wr_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg);
void bfq_release_process_ref(struct bfq_data *bfqd, struct bfq_queue *bfqq);
void bfq_schedule_dispatch(struct bfq_data *bfqd);
void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg);

Expand Down
Loading

0 comments on commit 10f36b1

Please sign in to comment.