Commit ee4a36f4 authored by Coly Li's avatar Coly Li Committed by Jens Axboe

bcache: use delayed kworker fo asynchronous devices registration

This patch changes the asynchronous registration kworker to a delayed
kworker. There is probability queue_work() queues the async registration
kworker to the same CPU (even though very little), then the process
which writing sysfs interface to reigster bcache device may won't return
immeidately. queue_delayed_work() in this patch will delay 10 jiffies
before insert the kworker to run queue, which makes sure the registering
process may always returns to user space in time.

Fixes: 9e23ccf8 ("bcache: asynchronous devices registration")
Signed-off-by: default avatarColy Li <colyli@suse.de>
Cc: Hannes Reinecke <hare@suse.de>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent dcacbc12
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/genhd.h> #include <linux/genhd.h>
#include <linux/idr.h> #include <linux/idr.h>
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/workqueue.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/random.h> #include <linux/random.h>
#include <linux/reboot.h> #include <linux/reboot.h>
...@@ -2380,7 +2381,7 @@ static bool bch_is_open(struct block_device *bdev) ...@@ -2380,7 +2381,7 @@ static bool bch_is_open(struct block_device *bdev)
} }
struct async_reg_args { struct async_reg_args {
struct work_struct reg_work; struct delayed_work reg_work;
char *path; char *path;
struct cache_sb *sb; struct cache_sb *sb;
struct cache_sb_disk *sb_disk; struct cache_sb_disk *sb_disk;
...@@ -2391,7 +2392,7 @@ static void register_bdev_worker(struct work_struct *work) ...@@ -2391,7 +2392,7 @@ static void register_bdev_worker(struct work_struct *work)
{ {
int fail = false; int fail = false;
struct async_reg_args *args = struct async_reg_args *args =
container_of(work, struct async_reg_args, reg_work); container_of(work, struct async_reg_args, reg_work.work);
struct cached_dev *dc; struct cached_dev *dc;
dc = kzalloc(sizeof(*dc), GFP_KERNEL); dc = kzalloc(sizeof(*dc), GFP_KERNEL);
...@@ -2421,7 +2422,7 @@ static void register_cache_worker(struct work_struct *work) ...@@ -2421,7 +2422,7 @@ static void register_cache_worker(struct work_struct *work)
{ {
int fail = false; int fail = false;
struct async_reg_args *args = struct async_reg_args *args =
container_of(work, struct async_reg_args, reg_work); container_of(work, struct async_reg_args, reg_work.work);
struct cache *ca; struct cache *ca;
ca = kzalloc(sizeof(*ca), GFP_KERNEL); ca = kzalloc(sizeof(*ca), GFP_KERNEL);
...@@ -2449,11 +2450,12 @@ static void register_cache_worker(struct work_struct *work) ...@@ -2449,11 +2450,12 @@ static void register_cache_worker(struct work_struct *work)
static void register_device_aync(struct async_reg_args *args) static void register_device_aync(struct async_reg_args *args)
{ {
if (SB_IS_BDEV(args->sb)) if (SB_IS_BDEV(args->sb))
INIT_WORK(&args->reg_work, register_bdev_worker); INIT_DELAYED_WORK(&args->reg_work, register_bdev_worker);
else else
INIT_WORK(&args->reg_work, register_cache_worker); INIT_DELAYED_WORK(&args->reg_work, register_cache_worker);
queue_work(system_wq, &args->reg_work); /* 10 jiffies is enough for a delay */
queue_delayed_work(system_wq, &args->reg_work, 10);
} }
static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr, static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment