Skip to content

Commit

Permalink
Merge tag 'block-5.14-2021-07-08' of git://git.kernel.dk/linux-block
Browse files Browse the repository at this point in the history
Pull more block updates from Jens Axboe:
 "A combination of changes that ended up depending on both the driver
  and core branch (and/or the IDE removal), and a few late arriving
  fixes. In detail:

   - Fix io ticks wrap-around issue (Chunguang)

   - nvme-tcp sock locking fix (Maurizio)

   - s390-dasd fixes (Kees, Christoph)

   - blk_execute_rq polling support (Keith)

   - blk-cgroup RCU iteration fix (Yu)

   - nbd backend ID addition (Prasanna)

   - Partition deletion fix (Yufen)

   - Use blk_mq_alloc_disk for mmc, mtip32xx, ubd (Christoph)

   - Removal of now dead block request types due to IDE removal
     (Christoph)

   - Loop probing and control device cleanups (Christoph)

   - Device uevent fix (Christoph)

   - Misc cleanups/fixes (Tetsuo, Christoph)"

* tag 'block-5.14-2021-07-08' of git://git.kernel.dk/linux-block: (34 commits)
  blk-cgroup: prevent rcu_sched detected stalls warnings while iterating blkgs
  block: fix the problem of io_ticks becoming smaller
  nvme-tcp: can't set sk_user_data without write_lock
  loop: remove unused variable in loop_set_status()
  block: remove the bdgrab in blk_drop_partitions
  block: grab a device refcount in disk_uevent
  s390/dasd: Avoid field over-reading memcpy()
  dasd: unexport dasd_set_target_state
  block: check disk exist before trying to add partition
  ubd: remove dead code in ubd_setup_common
  nvme: use return value from blk_execute_rq()
  block: return errors from blk_execute_rq()
  nvme: use blk_execute_rq() for passthrough commands
  block: support polling through blk_execute_rq
  block: remove REQ_OP_SCSI_{IN,OUT}
  block: mark blk_mq_init_queue_data static
  loop: rewrite loop_exit using idr_for_each_entry
  loop: split loop_lookup
  loop: don't allow deleting an unspecified loop device
  loop: move loop_ctl_mutex locking into loop_add
  ...
  • Loading branch information
Linus Torvalds committed Jul 9, 2021
2 parents 3de6295 + a731763 commit a022f7d
Show file tree
Hide file tree
Showing 43 changed files with 346 additions and 520 deletions.
160 changes: 26 additions & 134 deletions arch/um/drivers/ubd_kern.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,7 @@ static const struct block_device_operations ubd_blops = {
};

/* Protected by ubd_lock */
static int fake_major = UBD_MAJOR;
static struct gendisk *ubd_gendisk[MAX_DEV];
static struct gendisk *fake_gendisk[MAX_DEV];

#ifdef CONFIG_BLK_DEV_UBD_SYNC
#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 1, .c = 0, \
Expand Down Expand Up @@ -197,54 +195,19 @@ struct ubd {
/* Protected by ubd_lock */
static struct ubd ubd_devs[MAX_DEV] = { [0 ... MAX_DEV - 1] = DEFAULT_UBD };

/* Only changed by fake_ide_setup which is a setup */
static int fake_ide = 0;
static struct proc_dir_entry *proc_ide_root = NULL;
static struct proc_dir_entry *proc_ide = NULL;

static blk_status_t ubd_queue_rq(struct blk_mq_hw_ctx *hctx,
const struct blk_mq_queue_data *bd);

static void make_proc_ide(void)
{
proc_ide_root = proc_mkdir("ide", NULL);
proc_ide = proc_mkdir("ide0", proc_ide_root);
}

static int fake_ide_media_proc_show(struct seq_file *m, void *v)
{
seq_puts(m, "disk\n");
return 0;
}

static void make_ide_entries(const char *dev_name)
{
struct proc_dir_entry *dir, *ent;
char name[64];

if(proc_ide_root == NULL) make_proc_ide();

dir = proc_mkdir(dev_name, proc_ide);
if(!dir) return;

ent = proc_create_single("media", S_IRUGO, dir,
fake_ide_media_proc_show);
if(!ent) return;
snprintf(name, sizeof(name), "ide0/%s", dev_name);
proc_symlink(dev_name, proc_ide_root, name);
}

static int fake_ide_setup(char *str)
{
fake_ide = 1;
pr_warn("The fake_ide option has been removed\n");
return 1;
}

__setup("fake_ide", fake_ide_setup);

__uml_help(fake_ide_setup,
"fake_ide\n"
" Create ide0 entries that map onto ubd devices.\n\n"
" Obsolete stub.\n\n"
);

static int parse_unit(char **ptr)
Expand Down Expand Up @@ -280,36 +243,14 @@ static int ubd_setup_common(char *str, int *index_out, char **error_out)
if(index_out) *index_out = -1;
n = *str;
if(n == '='){
char *end;
int major;

str++;
if(!strcmp(str, "sync")){
global_openflags = of_sync(global_openflags);
return err;
}

err = -EINVAL;
major = simple_strtoul(str, &end, 0);
if((*end != '\0') || (end == str)){
*error_out = "Didn't parse major number";
return err;
}

mutex_lock(&ubd_lock);
if (fake_major != UBD_MAJOR) {
*error_out = "Can't assign a fake major twice";
goto out1;
}

fake_major = major;

printk(KERN_INFO "Setting extra ubd major number to %d\n",
major);
err = 0;
out1:
mutex_unlock(&ubd_lock);
return err;
pr_warn("fake major not supported any more\n");
return 0;
}

n = parse_unit(&str);
Expand Down Expand Up @@ -874,7 +815,6 @@ static void ubd_device_release(struct device *dev)
{
struct ubd *ubd_dev = dev_get_drvdata(dev);

blk_cleanup_queue(ubd_dev->queue);
blk_mq_free_tag_set(&ubd_dev->tag_set);
*ubd_dev = ((struct ubd) DEFAULT_UBD);
}
Expand Down Expand Up @@ -914,41 +854,25 @@ static const struct attribute_group *ubd_attr_groups[] = {
NULL,
};

static int ubd_disk_register(int major, u64 size, int unit,
struct gendisk **disk_out)
static void ubd_disk_register(int major, u64 size, int unit,
struct gendisk *disk)
{
struct device *parent = NULL;
struct gendisk *disk;

disk = alloc_disk(1 << UBD_SHIFT);
if(disk == NULL)
return -ENOMEM;

disk->major = major;
disk->first_minor = unit << UBD_SHIFT;
disk->minors = 1 << UBD_SHIFT;
disk->fops = &ubd_blops;
set_capacity(disk, size / 512);
if (major == UBD_MAJOR)
sprintf(disk->disk_name, "ubd%c", 'a' + unit);
else
sprintf(disk->disk_name, "ubd_fake%d", unit);

/* sysfs register (not for ide fake devices) */
if (major == UBD_MAJOR) {
ubd_devs[unit].pdev.id = unit;
ubd_devs[unit].pdev.name = DRIVER_NAME;
ubd_devs[unit].pdev.dev.release = ubd_device_release;
dev_set_drvdata(&ubd_devs[unit].pdev.dev, &ubd_devs[unit]);
platform_device_register(&ubd_devs[unit].pdev);
parent = &ubd_devs[unit].pdev.dev;
}
sprintf(disk->disk_name, "ubd%c", 'a' + unit);

ubd_devs[unit].pdev.id = unit;
ubd_devs[unit].pdev.name = DRIVER_NAME;
ubd_devs[unit].pdev.dev.release = ubd_device_release;
dev_set_drvdata(&ubd_devs[unit].pdev.dev, &ubd_devs[unit]);
platform_device_register(&ubd_devs[unit].pdev);

disk->private_data = &ubd_devs[unit];
disk->queue = ubd_devs[unit].queue;
device_add_disk(parent, disk, ubd_attr_groups);

*disk_out = disk;
return 0;
device_add_disk(&ubd_devs[unit].pdev.dev, disk, ubd_attr_groups);
}

#define ROUND_BLOCK(n) ((n + (SECTOR_SIZE - 1)) & (-SECTOR_SIZE))
Expand All @@ -960,6 +884,7 @@ static const struct blk_mq_ops ubd_mq_ops = {
static int ubd_add(int n, char **error_out)
{
struct ubd *ubd_dev = &ubd_devs[n];
struct gendisk *disk;
int err = 0;

if(ubd_dev->file == NULL)
Expand All @@ -984,43 +909,24 @@ static int ubd_add(int n, char **error_out)
if (err)
goto out;

ubd_dev->queue = blk_mq_init_queue(&ubd_dev->tag_set);
if (IS_ERR(ubd_dev->queue)) {
err = PTR_ERR(ubd_dev->queue);
disk = blk_mq_alloc_disk(&ubd_dev->tag_set, ubd_dev);
if (IS_ERR(disk)) {
err = PTR_ERR(disk);
goto out_cleanup_tags;
}
ubd_dev->queue = disk->queue;

ubd_dev->queue->queuedata = ubd_dev;
blk_queue_write_cache(ubd_dev->queue, true, false);

blk_queue_max_segments(ubd_dev->queue, MAX_SG);
blk_queue_segment_boundary(ubd_dev->queue, PAGE_SIZE - 1);
err = ubd_disk_register(UBD_MAJOR, ubd_dev->size, n, &ubd_gendisk[n]);
if(err){
*error_out = "Failed to register device";
goto out_cleanup_tags;
}

if (fake_major != UBD_MAJOR)
ubd_disk_register(fake_major, ubd_dev->size, n,
&fake_gendisk[n]);

/*
* Perhaps this should also be under the "if (fake_major)" above
* using the fake_disk->disk_name
*/
if (fake_ide)
make_ide_entries(ubd_gendisk[n]->disk_name);

err = 0;
out:
return err;
ubd_disk_register(UBD_MAJOR, ubd_dev->size, n, disk);
ubd_gendisk[n] = disk;
return 0;

out_cleanup_tags:
blk_mq_free_tag_set(&ubd_dev->tag_set);
if (!(IS_ERR(ubd_dev->queue)))
blk_cleanup_queue(ubd_dev->queue);
goto out;
out:
return err;
}

static int ubd_config(char *str, char **error_out)
Expand Down Expand Up @@ -1123,13 +1029,7 @@ static int ubd_remove(int n, char **error_out)
ubd_gendisk[n] = NULL;
if(disk != NULL){
del_gendisk(disk);
put_disk(disk);
}

if(fake_gendisk[n] != NULL){
del_gendisk(fake_gendisk[n]);
put_disk(fake_gendisk[n]);
fake_gendisk[n] = NULL;
blk_cleanup_disk(disk);
}

err = 0;
Expand Down Expand Up @@ -1188,14 +1088,6 @@ static int __init ubd_init(void)
if (register_blkdev(UBD_MAJOR, "ubd"))
return -1;

if (fake_major != UBD_MAJOR) {
char name[sizeof("ubd_nnn\0")];

snprintf(name, sizeof(name), "ubd_%d", fake_major);
if (register_blkdev(fake_major, "ubd"))
return -1;
}

irq_req_buffer = kmalloc_array(UBD_REQ_BUFFER_SIZE,
sizeof(struct io_thread_req *),
GFP_KERNEL
Expand Down
15 changes: 15 additions & 0 deletions block/blk-cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ static LIST_HEAD(all_blkcgs); /* protected by blkcg_pol_mutex */
bool blkcg_debug_stats = false;
static struct workqueue_struct *blkcg_punt_bio_wq;

#define BLKG_DESTROY_BATCH_SIZE 64

static bool blkcg_policy_enabled(struct request_queue *q,
const struct blkcg_policy *pol)
{
Expand Down Expand Up @@ -422,14 +424,27 @@ static void blkg_destroy(struct blkcg_gq *blkg)
static void blkg_destroy_all(struct request_queue *q)
{
struct blkcg_gq *blkg, *n;
int count = BLKG_DESTROY_BATCH_SIZE;

restart:
spin_lock_irq(&q->queue_lock);
list_for_each_entry_safe(blkg, n, &q->blkg_list, q_node) {
struct blkcg *blkcg = blkg->blkcg;

spin_lock(&blkcg->lock);
blkg_destroy(blkg);
spin_unlock(&blkcg->lock);

/*
* in order to avoid holding the spin lock for too long, release
* it when a batch of blkgs are destroyed.
*/
if (!(--count)) {
count = BLKG_DESTROY_BATCH_SIZE;
spin_unlock_irq(&q->queue_lock);
cond_resched();
goto restart;
}
}

q->root_blkg = NULL;
Expand Down
4 changes: 1 addition & 3 deletions block/blk-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,6 @@ static const char *const blk_op_name[] = {
REQ_OP_NAME(ZONE_APPEND),
REQ_OP_NAME(WRITE_SAME),
REQ_OP_NAME(WRITE_ZEROES),
REQ_OP_NAME(SCSI_IN),
REQ_OP_NAME(SCSI_OUT),
REQ_OP_NAME(DRV_IN),
REQ_OP_NAME(DRV_OUT),
};
Expand Down Expand Up @@ -1243,7 +1241,7 @@ static void update_io_ticks(struct block_device *part, unsigned long now,
unsigned long stamp;
again:
stamp = READ_ONCE(part->bd_stamp);
if (unlikely(stamp != now)) {
if (unlikely(time_after(now, stamp))) {
if (likely(cmpxchg(&part->bd_stamp, stamp, now) == stamp))
__part_stat_add(part, io_ticks, end ? now - stamp : 1);
}
Expand Down
25 changes: 22 additions & 3 deletions block/blk-exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ static void blk_end_sync_rq(struct request *rq, blk_status_t error)
{
struct completion *waiting = rq->end_io_data;

rq->end_io_data = NULL;
rq->end_io_data = (void *)(uintptr_t)error;

/*
* complete last, if this is a stack request the process (and thus
Expand Down Expand Up @@ -63,6 +63,19 @@ void blk_execute_rq_nowait(struct gendisk *bd_disk, struct request *rq,
}
EXPORT_SYMBOL_GPL(blk_execute_rq_nowait);

static bool blk_rq_is_poll(struct request *rq)
{
return rq->mq_hctx && rq->mq_hctx->type == HCTX_TYPE_POLL;
}

static void blk_rq_poll_completion(struct request *rq, struct completion *wait)
{
do {
blk_poll(rq->q, request_to_qc_t(rq->mq_hctx, rq), true);
cond_resched();
} while (!completion_done(wait));
}

/**
* blk_execute_rq - insert a request into queue for execution
* @bd_disk: matching gendisk
Expand All @@ -72,8 +85,9 @@ EXPORT_SYMBOL_GPL(blk_execute_rq_nowait);
* Description:
* Insert a fully prepared request at the back of the I/O scheduler queue
* for execution and wait for completion.
* Return: The blk_status_t result provided to blk_mq_end_request().
*/
void blk_execute_rq(struct gendisk *bd_disk, struct request *rq, int at_head)
blk_status_t blk_execute_rq(struct gendisk *bd_disk, struct request *rq, int at_head)
{
DECLARE_COMPLETION_ONSTACK(wait);
unsigned long hang_check;
Expand All @@ -83,9 +97,14 @@ void blk_execute_rq(struct gendisk *bd_disk, struct request *rq, int at_head)

/* Prevent hang_check timer from firing at us during very long I/O */
hang_check = sysctl_hung_task_timeout_secs;
if (hang_check)

if (blk_rq_is_poll(rq))
blk_rq_poll_completion(rq, &wait);
else if (hang_check)
while (!wait_for_completion_io_timeout(&wait, hang_check * (HZ/2)));
else
wait_for_completion_io(&wait);

return (blk_status_t)(uintptr_t)rq->end_io_data;
}
EXPORT_SYMBOL(blk_execute_rq);
3 changes: 1 addition & 2 deletions block/blk-mq.c
Original file line number Diff line number Diff line change
Expand Up @@ -3109,7 +3109,7 @@ void blk_mq_release(struct request_queue *q)
blk_mq_sysfs_deinit(q);
}

struct request_queue *blk_mq_init_queue_data(struct blk_mq_tag_set *set,
static struct request_queue *blk_mq_init_queue_data(struct blk_mq_tag_set *set,
void *queuedata)
{
struct request_queue *q;
Expand All @@ -3126,7 +3126,6 @@ struct request_queue *blk_mq_init_queue_data(struct blk_mq_tag_set *set,
}
return q;
}
EXPORT_SYMBOL_GPL(blk_mq_init_queue_data);

struct request_queue *blk_mq_init_queue(struct blk_mq_tag_set *set)
{
Expand Down
2 changes: 1 addition & 1 deletion block/bsg-lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ static int bsg_transport_fill_hdr(struct request *rq, struct sg_io_v4 *hdr,
return PTR_ERR(job->request);

if (hdr->dout_xfer_len && hdr->din_xfer_len) {
job->bidi_rq = blk_get_request(rq->q, REQ_OP_SCSI_IN, 0);
job->bidi_rq = blk_get_request(rq->q, REQ_OP_DRV_IN, 0);
if (IS_ERR(job->bidi_rq)) {
ret = PTR_ERR(job->bidi_rq);
goto out;
Expand Down
Loading

0 comments on commit a022f7d

Please sign in to comment.