History

Merge tag 'for-linus-20180906' of git://git.kernel.dk/linux-block

Pull block fixes from Jens Axboe: "Small collection of fixes that should go into this release. This contains: - Small series that fixes a race between blkcg teardown and writeback (Dennis Zhou) - Fix disallowing invalid block size settings from the nbd ioctl (me) - BFQ fix for a use-after-free on last release of a bfqg (Konstantin Khlebnikov) - Fix for the "don't warn for flush" fix (Mikulas)" * tag 'for-linus-20180906' of git://git.kernel.dk/linux-block: block: bfq: swap puts in bfqg_and_blkg_put block: don't warn when doing fsync on read-only devices nbd: don't allow invalid blocksize settings blkcg: use tryget logic when associating a blkg with a bio blkcg: delay blkg destruction until after writeback has finished Revert "blk-throttle: fix race between blkcg_bio_issue_check() and cgroup_rmdir()"

Linus Torvalds committed 8 years ago

Commit ca16eb32 parents db44bf4 d5274b38 files · +111 −64Browse files

Unified · Split

8 files
  1. block/bfq-cgroup.c +2 −2
  2. block/bio.c +2 −1
  3. block/blk-cgroup.c +48 −57
  4. block/blk-core.c +4 −1
  5. block/blk-throttle.c +3 −2
  6. drivers/block/nbd.c +3 −0
  7. include/linux/blk-cgroup.h +44 −1
  8. mm/backing-dev.c +5 −0
block/bfq-cgroup.c+2−2
@@ -275,9 +275,9 @@ static void bfqg_and_blkg_get(struct bfq_group *bfqg) · 274 unmodified lines
275 275
276void bfqg_and_blkg_put(struct bfq_group *bfqg)276void bfqg_and_blkg_put(struct bfq_group *bfqg)
277{277{
278 bfqg_put(bfqg);
279
280 blkg_put(bfqg_to_blkg(bfqg));278 blkg_put(bfqg_to_blkg(bfqg));
279
280 bfqg_put(bfqg);
281}281}
282 282
283/* @stats = 0 */283/* @stats = 0 */
block/bio.c+2−1
@@ -2015,7 +2015,8 @@ int bio_associate_blkg(struct bio *bio, struct blkcg_gq *blkg) · 2014 unmodified lines
2015{2015{
2016 if (unlikely(bio->bi_blkg))2016 if (unlikely(bio->bi_blkg))
2017 return -EBUSY;2017 return -EBUSY;
2018 blkg_get(blkg);2018 if (!blkg_try_get(blkg))
2019 return -ENODEV;
2019 bio->bi_blkg = blkg;2020 bio->bi_blkg = blkg;
2020 return 0;2021 return 0;
2021}2022}
block/blk-cgroup.c+48−57
@@ -310,28 +310,11 @@ struct blkcg_gq *blkg_lookup_create(struct blkcg *blkcg, · 309 unmodified lines
310 }310 }
311}311}
312 312
313static void blkg_pd_offline(struct blkcg_gq *blkg)
314{
315 int i;
316
317 lockdep_assert_held(blkg->q->queue_lock);
318 lockdep_assert_held(&blkg->blkcg->lock);
319
320 for (i = 0; i < BLKCG_MAX_POLS; i++) {
321 struct blkcg_policy *pol = blkcg_policy[i];
322
323 if (blkg->pd[i] && !blkg->pd[i]->offline &&
324 pol->pd_offline_fn) {
325 pol->pd_offline_fn(blkg->pd[i]);
326 blkg->pd[i]->offline = true;
327 }
328 }
329}
330
331static void blkg_destroy(struct blkcg_gq *blkg)313static void blkg_destroy(struct blkcg_gq *blkg)
332{314{
333 struct blkcg *blkcg = blkg->blkcg;315 struct blkcg *blkcg = blkg->blkcg;
334 struct blkcg_gq *parent = blkg->parent;316 struct blkcg_gq *parent = blkg->parent;
317 int i;
335 318
336 lockdep_assert_held(blkg->q->queue_lock);319 lockdep_assert_held(blkg->q->queue_lock);
337 lockdep_assert_held(&blkcg->lock);320 lockdep_assert_held(&blkcg->lock);
@@ -340,6 +323,13 @@ static void blkg_destroy(struct blkcg_gq *blkg) · 2 unmodified lines
340 WARN_ON_ONCE(list_empty(&blkg->q_node));323 WARN_ON_ONCE(list_empty(&blkg->q_node));
341 WARN_ON_ONCE(hlist_unhashed(&blkg->blkcg_node));324 WARN_ON_ONCE(hlist_unhashed(&blkg->blkcg_node));
342 325
326 for (i = 0; i < BLKCG_MAX_POLS; i++) {
327 struct blkcg_policy *pol = blkcg_policy[i];
328
329 if (blkg->pd[i] && pol->pd_offline_fn)
330 pol->pd_offline_fn(blkg->pd[i]);
331 }
332
343 if (parent) {333 if (parent) {
344 blkg_rwstat_add_aux(&parent->stat_bytes, &blkg->stat_bytes);334 blkg_rwstat_add_aux(&parent->stat_bytes, &blkg->stat_bytes);
345 blkg_rwstat_add_aux(&parent->stat_ios, &blkg->stat_ios);335 blkg_rwstat_add_aux(&parent->stat_ios, &blkg->stat_ios);
@@ -382,7 +372,6 @@ static void blkg_destroy_all(struct request_queue *q) · 36 unmodified lines
382 struct blkcg *blkcg = blkg->blkcg;372 struct blkcg *blkcg = blkg->blkcg;
383 373
384 spin_lock(&blkcg->lock);374 spin_lock(&blkcg->lock);
385 blkg_pd_offline(blkg);
386 blkg_destroy(blkg);375 blkg_destroy(blkg);
387 spin_unlock(&blkcg->lock);376 spin_unlock(&blkcg->lock);
388 }377 }
@@ -1053,59 +1042,64 @@ static struct cftype blkcg_legacy_files[] = { · 664 unmodified lines
1053 { } /* terminate */1042 { } /* terminate */
1054};1043};
1055 1044
1045/*
1046 * blkcg destruction is a three-stage process.
1047 *
1048 * 1. Destruction starts. The blkcg_css_offline() callback is invoked
1049 * which offlines writeback. Here we tie the next stage of blkg destruction
1050 * to the completion of writeback associated with the blkcg. This lets us
1051 * avoid punting potentially large amounts of outstanding writeback to root
1052 * while maintaining any ongoing policies. The next stage is triggered when
1053 * the nr_cgwbs count goes to zero.
1054 *
1055 * 2. When the nr_cgwbs count goes to zero, blkcg_destroy_blkgs() is called
1056 * and handles the destruction of blkgs. Here the css reference held by
1057 * the blkg is put back eventually allowing blkcg_css_free() to be called.
1058 * This work may occur in cgwb_release_workfn() on the cgwb_release
1059 * workqueue. Any submitted ios that fail to get the blkg ref will be
1060 * punted to the root_blkg.
1061 *
1062 * 3. Once the blkcg ref count goes to zero, blkcg_css_free() is called.
1063 * This finally frees the blkcg.
1064 */
1065
1056/**1066/**
1057 * blkcg_css_offline - cgroup css_offline callback1067 * blkcg_css_offline - cgroup css_offline callback
1058 * @css: css of interest1068 * @css: css of interest
1059 *1069 *
1060 * This function is called when @css is about to go away and responsible1070 * This function is called when @css is about to go away. Here the cgwbs are
1061 * for offlining all blkgs pd and killing all wbs associated with @css.1071 * offlined first and only once writeback associated with the blkcg has
1062 * blkgs pd offline should be done while holding both q and blkcg locks.1072 * finished do we start step 2 (see above).
1063 * As blkcg lock is nested inside q lock, this function performs reverse
1064 * double lock dancing.
1065 *
1066 * This is the blkcg counterpart of ioc_release_fn().
1067 */1073 */
1068static void blkcg_css_offline(struct cgroup_subsys_state *css)1074static void blkcg_css_offline(struct cgroup_subsys_state *css)
1069{1075{
1070 struct blkcg *blkcg = css_to_blkcg(css);1076 struct blkcg *blkcg = css_to_blkcg(css);
1071 struct blkcg_gq *blkg;
1072
1073 spin_lock_irq(&blkcg->lock);
1074
1075 hlist_for_each_entry(blkg, &blkcg->blkg_list, blkcg_node) {
1076 struct request_queue *q = blkg->q;
1077
1078 if (spin_trylock(q->queue_lock)) {
1079 blkg_pd_offline(blkg);
1080 spin_unlock(q->queue_lock);
1081 } else {
1082 spin_unlock_irq(&blkcg->lock);
1083 cpu_relax();
1084 spin_lock_irq(&blkcg->lock);
1085 }
1086 }
1087
1088 spin_unlock_irq(&blkcg->lock);
1089 1077
1078 /* this prevents anyone from attaching or migrating to this blkcg */
1090 wb_blkcg_offline(blkcg);1079 wb_blkcg_offline(blkcg);
1080
1081 /* put the base cgwb reference allowing step 2 to be triggered */
1082 blkcg_cgwb_put(blkcg);
1091}1083}
1092 1084
1093/**1085/**
1094 * blkcg_destroy_all_blkgs - destroy all blkgs associated with a blkcg1086 * blkcg_destroy_blkgs - responsible for shooting down blkgs
1095 * @blkcg: blkcg of interest1087 * @blkcg: blkcg of interest
1096 *1088 *
1097 * This function is called when blkcg css is about to free and responsible for1089 * blkgs should be removed while holding both q and blkcg locks. As blkcg lock
1098 * destroying all blkgs associated with @blkcg.
1099 * blkgs should be removed while holding both q and blkcg locks. As blkcg lock
1100 * is nested inside q lock, this function performs reverse double lock dancing.1090 * is nested inside q lock, this function performs reverse double lock dancing.
1091 * Destroying the blkgs releases the reference held on the blkcg's css allowing
1092 * blkcg_css_free to eventually be called.
1093 *
1094 * This is the blkcg counterpart of ioc_release_fn().
1101 */1095 */
1102static void blkcg_destroy_all_blkgs(struct blkcg *blkcg)1096void blkcg_destroy_blkgs(struct blkcg *blkcg)
1103{1097{
1104 spin_lock_irq(&blkcg->lock);1098 spin_lock_irq(&blkcg->lock);
1099
1105 while (!hlist_empty(&blkcg->blkg_list)) {1100 while (!hlist_empty(&blkcg->blkg_list)) {
1106 struct blkcg_gq *blkg = hlist_entry(blkcg->blkg_list.first,1101 struct blkcg_gq *blkg = hlist_entry(blkcg->blkg_list.first,
1107 struct blkcg_gq,1102 struct blkcg_gq, blkcg_node);
1108 blkcg_node);
1109 struct request_queue *q = blkg->q;1103 struct request_queue *q = blkg->q;
1110 1104
1111 if (spin_trylock(q->queue_lock)) {1105 if (spin_trylock(q->queue_lock)) {
@@ -1117,6 +1111,7 @@ static void blkcg_destroy_all_blkgs(struct blkcg *blkcg) · 5 unmodified lines
1117 spin_lock_irq(&blkcg->lock);1111 spin_lock_irq(&blkcg->lock);
1118 }1112 }
1119 }1113 }
1114
1120 spin_unlock_irq(&blkcg->lock);1115 spin_unlock_irq(&blkcg->lock);
1121}1116}
1122 1117
@@ -1125,8 +1120,6 @@ static void blkcg_css_free(struct cgroup_subsys_state *css) · 2 unmodified lines
1125 struct blkcg *blkcg = css_to_blkcg(css);1120 struct blkcg *blkcg = css_to_blkcg(css);
1126 int i;1121 int i;
1127 1122
1128 blkcg_destroy_all_blkgs(blkcg);
1129
1130 mutex_lock(&blkcg_pol_mutex);1123 mutex_lock(&blkcg_pol_mutex);
1131 1124
1132 list_del(&blkcg->all_blkcgs_node);1125 list_del(&blkcg->all_blkcgs_node);
@@ -1189,6 +1182,7 @@ blkcg_css_alloc(struct cgroup_subsys_state *parent_css) · 56 unmodified lines
1189 INIT_HLIST_HEAD(&blkcg->blkg_list);1182 INIT_HLIST_HEAD(&blkcg->blkg_list);
1190#ifdef CONFIG_CGROUP_WRITEBACK1183#ifdef CONFIG_CGROUP_WRITEBACK
1191 INIT_LIST_HEAD(&blkcg->cgwb_list);1184 INIT_LIST_HEAD(&blkcg->cgwb_list);
1185 refcount_set(&blkcg->cgwb_refcnt, 1);
1192#endif1186#endif
1193 list_add_tail(&blkcg->all_blkcgs_node, &all_blkcgs);1187 list_add_tail(&blkcg->all_blkcgs_node, &all_blkcgs);
1194 1188
@@ -1480,11 +1474,8 @@ void blkcg_deactivate_policy(struct request_queue *q, · 285 unmodified lines
1480 1474
1481 list_for_each_entry(blkg, &q->blkg_list, q_node) {1475 list_for_each_entry(blkg, &q->blkg_list, q_node) {
1482 if (blkg->pd[pol->plid]) {1476 if (blkg->pd[pol->plid]) {
1483 if (!blkg->pd[pol->plid]->offline &&1477 if (pol->pd_offline_fn)
1484 pol->pd_offline_fn) {
1485 pol->pd_offline_fn(blkg->pd[pol->plid]);1478 pol->pd_offline_fn(blkg->pd[pol->plid]);
1486 blkg->pd[pol->plid]->offline = true;
1487 }
1488 pol->pd_free_fn(blkg->pd[pol->plid]);1479 pol->pd_free_fn(blkg->pd[pol->plid]);
1489 blkg->pd[pol->plid] = NULL;1480 blkg->pd[pol->plid] = NULL;
1490 }1481 }
block/blk-core.c+4−1
@@ -2163,9 +2163,12 @@ static inline bool bio_check_ro(struct bio *bio, struct hd_struct *part) · 2162 unmodified lines
2163{2163{
2164 const int op = bio_op(bio);2164 const int op = bio_op(bio);
2165 2165
2166 if (part->policy && (op_is_write(op) && !op_is_flush(op))) {2166 if (part->policy && op_is_write(op)) {
2167 char b[BDEVNAME_SIZE];2167 char b[BDEVNAME_SIZE];
2168 2168
2169 if (op_is_flush(bio->bi_opf) && !bio_sectors(bio))
2170 return false;
2171
2169 WARN_ONCE(1,2172 WARN_ONCE(1,
2170 "generic_make_request: Trying to write "2173 "generic_make_request: Trying to write "
2171 "to read-only block-device %s (partno %d)\n",2174 "to read-only block-device %s (partno %d)\n",
block/blk-throttle.c+3−2
@@ -2129,8 +2129,9 @@ static inline void throtl_update_latency_buckets(struct throtl_data *td) · 2128 unmodified lines
2129static void blk_throtl_assoc_bio(struct throtl_grp *tg, struct bio *bio)2129static void blk_throtl_assoc_bio(struct throtl_grp *tg, struct bio *bio)
2130{2130{
2131#ifdef CONFIG_BLK_DEV_THROTTLING_LOW2131#ifdef CONFIG_BLK_DEV_THROTTLING_LOW
2132 if (bio->bi_css)2132 /* fallback to root_blkg if we fail to get a blkg ref */
2133 bio_associate_blkg(bio, tg_to_blkg(tg));2133 if (bio->bi_css && (bio_associate_blkg(bio, tg_to_blkg(tg)) == -ENODEV))
2134 bio_associate_blkg(bio, bio->bi_disk->queue->root_blkg);
2134 bio_issue_init(&bio->bi_issue, bio_sectors(bio));2135 bio_issue_init(&bio->bi_issue, bio_sectors(bio));
2135#endif2136#endif
2136}2137}
drivers/block/nbd.c+3−0
@@ -1239,6 +1239,9 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, · 1238 unmodified lines
1239 case NBD_SET_SOCK:1239 case NBD_SET_SOCK:
1240 return nbd_add_socket(nbd, arg, false);1240 return nbd_add_socket(nbd, arg, false);
1241 case NBD_SET_BLKSIZE:1241 case NBD_SET_BLKSIZE:
1242 if (!arg || !is_power_of_2(arg) || arg < 512 ||
1243 arg > PAGE_SIZE)
1244 return -EINVAL;
1242 nbd_size_set(nbd, arg,1245 nbd_size_set(nbd, arg,
1243 div_s64(config->bytesize, arg));1246 div_s64(config->bytesize, arg));
1244 return 0;1247 return 0;
include/linux/blk-cgroup.h+44−1
@@ -56,6 +56,7 @@ struct blkcg { · 55 unmodified lines
56 struct list_head all_blkcgs_node;56 struct list_head all_blkcgs_node;
57#ifdef CONFIG_CGROUP_WRITEBACK57#ifdef CONFIG_CGROUP_WRITEBACK
58 struct list_head cgwb_list;58 struct list_head cgwb_list;
59 refcount_t cgwb_refcnt;
59#endif60#endif
60};61};
61 62
@@ -89,7 +90,6 @@ struct blkg_policy_data { · 27 unmodified lines
89 /* the blkg and policy id this per-policy data belongs to */90 /* the blkg and policy id this per-policy data belongs to */
90 struct blkcg_gq *blkg;91 struct blkcg_gq *blkg;
91 int plid;92 int plid;
92 bool offline;
93};93};
94 94
95/*95/*
@@ -387,6 +387,49 @@ static inline struct blkcg *cpd_to_blkcg(struct blkcg_policy_data *cpd) · 291 unmodified lines
387 return cpd ? cpd->blkcg : NULL;387 return cpd ? cpd->blkcg : NULL;
388}388}
389 389
390extern void blkcg_destroy_blkgs(struct blkcg *blkcg);
391
392#ifdef CONFIG_CGROUP_WRITEBACK
393
394/**
395 * blkcg_cgwb_get - get a reference for blkcg->cgwb_list
396 * @blkcg: blkcg of interest
397 *
398 * This is used to track the number of active wb's related to a blkcg.
399 */
400static inline void blkcg_cgwb_get(struct blkcg *blkcg)
401{
402 refcount_inc(&blkcg->cgwb_refcnt);
403}
404
405/**
406 * blkcg_cgwb_put - put a reference for @blkcg->cgwb_list
407 * @blkcg: blkcg of interest
408 *
409 * This is used to track the number of active wb's related to a blkcg.
410 * When this count goes to zero, all active wb has finished so the
411 * blkcg can continue destruction by calling blkcg_destroy_blkgs().
412 * This work may occur in cgwb_release_workfn() on the cgwb_release
413 * workqueue.
414 */
415static inline void blkcg_cgwb_put(struct blkcg *blkcg)
416{
417 if (refcount_dec_and_test(&blkcg->cgwb_refcnt))
418 blkcg_destroy_blkgs(blkcg);
419}
420
421#else
422
423static inline void blkcg_cgwb_get(struct blkcg *blkcg) { }
424
425static inline void blkcg_cgwb_put(struct blkcg *blkcg)
426{
427 /* wb isn't being accounted, so trigger destruction right away */
428 blkcg_destroy_blkgs(blkcg);
429}
430
431#endif
432
390/**433/**
391 * blkg_path - format cgroup path of blkg434 * blkg_path - format cgroup path of blkg
392 * @blkg: blkg of interest435 * @blkg: blkg of interest
mm/backing-dev.c+5−0
@@ -491,6 +491,7 @@ static void cgwb_release_workfn(struct work_struct *work) · 490 unmodified lines
491{491{
492 struct bdi_writeback *wb = container_of(work, struct bdi_writeback,492 struct bdi_writeback *wb = container_of(work, struct bdi_writeback,
493 release_work);493 release_work);
494 struct blkcg *blkcg = css_to_blkcg(wb->blkcg_css);
494 495
495 mutex_lock(&wb->bdi->cgwb_release_mutex);496 mutex_lock(&wb->bdi->cgwb_release_mutex);
496 wb_shutdown(wb);497 wb_shutdown(wb);
@@ -499,6 +500,9 @@ static void cgwb_release_workfn(struct work_struct *work) · 2 unmodified lines
499 css_put(wb->blkcg_css);500 css_put(wb->blkcg_css);
500 mutex_unlock(&wb->bdi->cgwb_release_mutex);501 mutex_unlock(&wb->bdi->cgwb_release_mutex);
501 502
503 /* triggers blkg destruction if cgwb_refcnt becomes zero */
504 blkcg_cgwb_put(blkcg);
505
502 fprop_local_destroy_percpu(&wb->memcg_completions);506 fprop_local_destroy_percpu(&wb->memcg_completions);
503 percpu_ref_exit(&wb->refcnt);507 percpu_ref_exit(&wb->refcnt);
504 wb_exit(wb);508 wb_exit(wb);
@@ -597,6 +601,7 @@ static int cgwb_create(struct backing_dev_info *bdi, · 92 unmodified lines
597 list_add_tail_rcu(&wb->bdi_node, &bdi->wb_list);601 list_add_tail_rcu(&wb->bdi_node, &bdi->wb_list);
598 list_add(&wb->memcg_node, memcg_cgwb_list);602 list_add(&wb->memcg_node, memcg_cgwb_list);
599 list_add(&wb->blkcg_node, blkcg_cgwb_list);603 list_add(&wb->blkcg_node, blkcg_cgwb_list);
604 blkcg_cgwb_get(blkcg);
600 css_get(memcg_css);605 css_get(memcg_css);
601 css_get(blkcg_css);606 css_get(blkcg_css);
602 }607 }