diff options
-rw-r--r-- | block/blk-core.c | 7 | ||||
-rw-r--r-- | block/blk-throttle.c | 29 | ||||
-rw-r--r-- | include/linux/blkdev.h | 3 |
3 files changed, 18 insertions, 21 deletions
diff --git a/block/blk-core.c b/block/blk-core.c index 2f4002f79a24..792ece276160 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
@@ -2610,13 +2610,6 @@ int kblockd_schedule_work(struct request_queue *q, struct work_struct *work) | |||
2610 | } | 2610 | } |
2611 | EXPORT_SYMBOL(kblockd_schedule_work); | 2611 | EXPORT_SYMBOL(kblockd_schedule_work); |
2612 | 2612 | ||
2613 | int kblockd_schedule_delayed_work(struct request_queue *q, | ||
2614 | struct delayed_work *dwork, unsigned long delay) | ||
2615 | { | ||
2616 | return queue_delayed_work(kblockd_workqueue, dwork, delay); | ||
2617 | } | ||
2618 | EXPORT_SYMBOL(kblockd_schedule_delayed_work); | ||
2619 | |||
2620 | int __init blk_dev_init(void) | 2613 | int __init blk_dev_init(void) |
2621 | { | 2614 | { |
2622 | BUILD_BUG_ON(__REQ_NR_BITS > 8 * | 2615 | BUILD_BUG_ON(__REQ_NR_BITS > 8 * |
diff --git a/block/blk-throttle.c b/block/blk-throttle.c index a89043a3caa4..e36cc10a346c 100644 --- a/block/blk-throttle.c +++ b/block/blk-throttle.c | |||
@@ -20,6 +20,11 @@ static int throtl_quantum = 32; | |||
20 | /* Throttling is performed over 100ms slice and after that slice is renewed */ | 20 | /* Throttling is performed over 100ms slice and after that slice is renewed */ |
21 | static unsigned long throtl_slice = HZ/10; /* 100 ms */ | 21 | static unsigned long throtl_slice = HZ/10; /* 100 ms */ |
22 | 22 | ||
23 | /* A workqueue to queue throttle related work */ | ||
24 | static struct workqueue_struct *kthrotld_workqueue; | ||
25 | static void throtl_schedule_delayed_work(struct throtl_data *td, | ||
26 | unsigned long delay); | ||
27 | |||
23 | struct throtl_rb_root { | 28 | struct throtl_rb_root { |
24 | struct rb_root rb; | 29 | struct rb_root rb; |
25 | struct rb_node *left; | 30 | struct rb_node *left; |
@@ -345,10 +350,9 @@ static void throtl_schedule_next_dispatch(struct throtl_data *td) | |||
345 | update_min_dispatch_time(st); | 350 | update_min_dispatch_time(st); |
346 | 351 | ||
347 | if (time_before_eq(st->min_disptime, jiffies)) | 352 | if (time_before_eq(st->min_disptime, jiffies)) |
348 | throtl_schedule_delayed_work(td->queue, 0); | 353 | throtl_schedule_delayed_work(td, 0); |
349 | else | 354 | else |
350 | throtl_schedule_delayed_work(td->queue, | 355 | throtl_schedule_delayed_work(td, (st->min_disptime - jiffies)); |
351 | (st->min_disptime - jiffies)); | ||
352 | } | 356 | } |
353 | 357 | ||
354 | static inline void | 358 | static inline void |
@@ -815,10 +819,10 @@ void blk_throtl_work(struct work_struct *work) | |||
815 | } | 819 | } |
816 | 820 | ||
817 | /* Call with queue lock held */ | 821 | /* Call with queue lock held */ |
818 | void throtl_schedule_delayed_work(struct request_queue *q, unsigned long delay) | 822 | static void |
823 | throtl_schedule_delayed_work(struct throtl_data *td, unsigned long delay) | ||
819 | { | 824 | { |
820 | 825 | ||
821 | struct throtl_data *td = q->td; | ||
822 | struct delayed_work *dwork = &td->throtl_work; | 826 | struct delayed_work *dwork = &td->throtl_work; |
823 | 827 | ||
824 | if (total_nr_queued(td) > 0) { | 828 | if (total_nr_queued(td) > 0) { |
@@ -827,12 +831,11 @@ void throtl_schedule_delayed_work(struct request_queue *q, unsigned long delay) | |||
827 | * Cancel that and schedule a new one. | 831 | * Cancel that and schedule a new one. |
828 | */ | 832 | */ |
829 | __cancel_delayed_work(dwork); | 833 | __cancel_delayed_work(dwork); |
830 | kblockd_schedule_delayed_work(q, dwork, delay); | 834 | queue_delayed_work(kthrotld_workqueue, dwork, delay); |
831 | throtl_log(td, "schedule work. delay=%lu jiffies=%lu", | 835 | throtl_log(td, "schedule work. delay=%lu jiffies=%lu", |
832 | delay, jiffies); | 836 | delay, jiffies); |
833 | } | 837 | } |
834 | } | 838 | } |
835 | EXPORT_SYMBOL(throtl_schedule_delayed_work); | ||
836 | 839 | ||
837 | static void | 840 | static void |
838 | throtl_destroy_tg(struct throtl_data *td, struct throtl_grp *tg) | 841 | throtl_destroy_tg(struct throtl_data *td, struct throtl_grp *tg) |
@@ -920,7 +923,7 @@ static void throtl_update_blkio_group_read_bps(void *key, | |||
920 | smp_mb__after_atomic_inc(); | 923 | smp_mb__after_atomic_inc(); |
921 | 924 | ||
922 | /* Schedule a work now to process the limit change */ | 925 | /* Schedule a work now to process the limit change */ |
923 | throtl_schedule_delayed_work(td->queue, 0); | 926 | throtl_schedule_delayed_work(td, 0); |
924 | } | 927 | } |
925 | 928 | ||
926 | static void throtl_update_blkio_group_write_bps(void *key, | 929 | static void throtl_update_blkio_group_write_bps(void *key, |
@@ -934,7 +937,7 @@ static void throtl_update_blkio_group_write_bps(void *key, | |||
934 | smp_mb__before_atomic_inc(); | 937 | smp_mb__before_atomic_inc(); |
935 | atomic_inc(&td->limits_changed); | 938 | atomic_inc(&td->limits_changed); |
936 | smp_mb__after_atomic_inc(); | 939 | smp_mb__after_atomic_inc(); |
937 | throtl_schedule_delayed_work(td->queue, 0); | 940 | throtl_schedule_delayed_work(td, 0); |
938 | } | 941 | } |
939 | 942 | ||
940 | static void throtl_update_blkio_group_read_iops(void *key, | 943 | static void throtl_update_blkio_group_read_iops(void *key, |
@@ -948,7 +951,7 @@ static void throtl_update_blkio_group_read_iops(void *key, | |||
948 | smp_mb__before_atomic_inc(); | 951 | smp_mb__before_atomic_inc(); |
949 | atomic_inc(&td->limits_changed); | 952 | atomic_inc(&td->limits_changed); |
950 | smp_mb__after_atomic_inc(); | 953 | smp_mb__after_atomic_inc(); |
951 | throtl_schedule_delayed_work(td->queue, 0); | 954 | throtl_schedule_delayed_work(td, 0); |
952 | } | 955 | } |
953 | 956 | ||
954 | static void throtl_update_blkio_group_write_iops(void *key, | 957 | static void throtl_update_blkio_group_write_iops(void *key, |
@@ -962,7 +965,7 @@ static void throtl_update_blkio_group_write_iops(void *key, | |||
962 | smp_mb__before_atomic_inc(); | 965 | smp_mb__before_atomic_inc(); |
963 | atomic_inc(&td->limits_changed); | 966 | atomic_inc(&td->limits_changed); |
964 | smp_mb__after_atomic_inc(); | 967 | smp_mb__after_atomic_inc(); |
965 | throtl_schedule_delayed_work(td->queue, 0); | 968 | throtl_schedule_delayed_work(td, 0); |
966 | } | 969 | } |
967 | 970 | ||
968 | void throtl_shutdown_timer_wq(struct request_queue *q) | 971 | void throtl_shutdown_timer_wq(struct request_queue *q) |
@@ -1135,6 +1138,10 @@ void blk_throtl_exit(struct request_queue *q) | |||
1135 | 1138 | ||
1136 | static int __init throtl_init(void) | 1139 | static int __init throtl_init(void) |
1137 | { | 1140 | { |
1141 | kthrotld_workqueue = alloc_workqueue("kthrotld", WQ_MEM_RECLAIM, 0); | ||
1142 | if (!kthrotld_workqueue) | ||
1143 | panic("Failed to create kthrotld\n"); | ||
1144 | |||
1138 | blkio_policy_register(&blkio_policy_throtl); | 1145 | blkio_policy_register(&blkio_policy_throtl); |
1139 | return 0; | 1146 | return 0; |
1140 | } | 1147 | } |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 4d18ff34670a..dd8cd0f47e3a 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -1088,7 +1088,6 @@ static inline void put_dev_sector(Sector p) | |||
1088 | 1088 | ||
1089 | struct work_struct; | 1089 | struct work_struct; |
1090 | int kblockd_schedule_work(struct request_queue *q, struct work_struct *work); | 1090 | int kblockd_schedule_work(struct request_queue *q, struct work_struct *work); |
1091 | int kblockd_schedule_delayed_work(struct request_queue *q, struct delayed_work *dwork, unsigned long delay); | ||
1092 | 1091 | ||
1093 | #ifdef CONFIG_BLK_CGROUP | 1092 | #ifdef CONFIG_BLK_CGROUP |
1094 | /* | 1093 | /* |
@@ -1136,7 +1135,6 @@ static inline uint64_t rq_io_start_time_ns(struct request *req) | |||
1136 | extern int blk_throtl_init(struct request_queue *q); | 1135 | extern int blk_throtl_init(struct request_queue *q); |
1137 | extern void blk_throtl_exit(struct request_queue *q); | 1136 | extern void blk_throtl_exit(struct request_queue *q); |
1138 | extern int blk_throtl_bio(struct request_queue *q, struct bio **bio); | 1137 | extern int blk_throtl_bio(struct request_queue *q, struct bio **bio); |
1139 | extern void throtl_schedule_delayed_work(struct request_queue *q, unsigned long delay); | ||
1140 | extern void throtl_shutdown_timer_wq(struct request_queue *q); | 1138 | extern void throtl_shutdown_timer_wq(struct request_queue *q); |
1141 | #else /* CONFIG_BLK_DEV_THROTTLING */ | 1139 | #else /* CONFIG_BLK_DEV_THROTTLING */ |
1142 | static inline int blk_throtl_bio(struct request_queue *q, struct bio **bio) | 1140 | static inline int blk_throtl_bio(struct request_queue *q, struct bio **bio) |
@@ -1146,7 +1144,6 @@ static inline int blk_throtl_bio(struct request_queue *q, struct bio **bio) | |||
1146 | 1144 | ||
1147 | static inline int blk_throtl_init(struct request_queue *q) { return 0; } | 1145 | static inline int blk_throtl_init(struct request_queue *q) { return 0; } |
1148 | static inline int blk_throtl_exit(struct request_queue *q) { return 0; } | 1146 | static inline int blk_throtl_exit(struct request_queue *q) { return 0; } |
1149 | static inline void throtl_schedule_delayed_work(struct request_queue *q, unsigned long delay) {} | ||
1150 | static inline void throtl_shutdown_timer_wq(struct request_queue *q) {} | 1147 | static inline void throtl_shutdown_timer_wq(struct request_queue *q) {} |
1151 | #endif /* CONFIG_BLK_DEV_THROTTLING */ | 1148 | #endif /* CONFIG_BLK_DEV_THROTTLING */ |
1152 | 1149 | ||