History

blkcg: implement per-queue policy activation

All blkcg policies were assumed to be enabled on all request_queues. Due to various implementation obstacles, during the recent blkcg core updates, this was temporarily implemented as shooting down all !root blkgs on elevator switch and policy [de]registration combined with half-broken in-place root blkg updates. In addition to being buggy and racy, this meant losing all blkcg configurations across those events. Now that blkcg is cleaned up enough, this patch replaces the temporary implementation with proper per-queue policy activation. Each blkcg policy should call the new blkcg_[de]activate_policy() to enable and disable the policy on a specific queue. blkcg_activate_policy() allocates and installs policy data for the policy for all existing blkgs. blkcg_deactivate_policy() does the reverse. If a policy is not enabled for a given queue, blkg printing / config functions skip the respective blkg for the queue. blkcg_activate_policy() also takes care of root blkg creation, and cfq_init_queue() and blk_throtl_init() are updated accordingly. This replaces blkcg_bypass_{start|end}() and update_root_blkg_pd() unnecessary. Dropped. v2: cfq_init_queue() was returning uninitialized @ret on root_group alloc failure if !CONFIG_CFQ_GROUP_IOSCHED. Fixed.

Tejun Heo committed 14 years ago

Commit a2b16931 parent 03d8e116 files · +201 −134Browse files

Unified · Split

6 files
  1. block/blk-cgroup.c +154 −74
  2. block/blk-cgroup.h +11 −4
  3. block/blk-throttle.c +19 −33
  4. block/cfq-iosched.c +16 −21
  5. block/elevator.c +0 −2
  6. include/linux/blkdev.h +1 −0
block/blk-cgroup.c+154−74
@@ -54,6 +54,17 @@ struct blkio_cgroup *bio_blkio_cgroup(struct bio *bio) · 53 unmodified lines
5454 }
5555 EXPORT_SYMBOL_GPL(bio_blkio_cgroup);
5656
57+static bool blkcg_policy_enabled(struct request_queue *q,
58+ const struct blkio_policy_type *pol)
59+{
60+ return pol && test_bit(pol->plid, q->blkcg_pols);
61+}
62+
63+static size_t blkg_pd_size(const struct blkio_policy_type *pol)
64+{
65+ return sizeof(struct blkg_policy_data) + pol->pdata_size;
66+}
67+
5768 /**
5869 * blkg_free - free a blkg
5970 * @blkg: blkg to free
@@ -111,12 +122,11 @@ static struct blkio_group *blkg_alloc(struct blkio_cgroup *blkcg, · 51 unmodified lines
111122 struct blkio_policy_type *pol = blkio_policy[i];
112123 struct blkg_policy_data *pd;
113124
114− if (!pol)
125+ if (!blkcg_policy_enabled(q, pol))
115126 continue;
116127
117128 /* alloc per-policy data and attach it to blkg */
118− pd = kzalloc_node(sizeof(*pd) + pol->pdata_size, GFP_ATOMIC,
119− q->node);
129+ pd = kzalloc_node(blkg_pd_size(pol), GFP_ATOMIC, q->node);
120130 if (!pd) {
121131 blkg_free(blkg);
122132 return NULL;
@@ -130,7 +140,7 @@ static struct blkio_group *blkg_alloc(struct blkio_cgroup *blkcg, · 7 unmodified lines
130140 for (i = 0; i < BLKCG_MAX_POLS; i++) {
131141 struct blkio_policy_type *pol = blkio_policy[i];
132142
133− if (pol)
143+ if (blkcg_policy_enabled(blkg->q, pol))
134144 pol->ops.blkio_init_group_fn(blkg);
135145 }
136146
@@ -236,36 +246,6 @@ static void blkg_destroy(struct blkio_group *blkg) · 99 unmodified lines
236246 blkg_put(blkg);
237247 }
238248
239−/*
240− * XXX: This updates blkg policy data in-place for root blkg, which is
241− * necessary across elevator switch and policy registration as root blkgs
242− * aren't shot down. This broken and racy implementation is temporary.
243− * Eventually, blkg shoot down will be replaced by proper in-place update.
244− */
245−void update_root_blkg_pd(struct request_queue *q,
246− const struct blkio_policy_type *pol)
247−{
248− struct blkio_group *blkg = blkg_lookup(&blkio_root_cgroup, q);
249− struct blkg_policy_data *pd;
250−
251− if (!blkg)
252− return;
253−
254− kfree(blkg->pd[pol->plid]);
255− blkg->pd[pol->plid] = NULL;
256−
257− if (!pol)
258− return;
259−
260− pd = kzalloc(sizeof(*pd) + pol->pdata_size, GFP_KERNEL);
261− WARN_ON_ONCE(!pd);
262−
263− blkg->pd[pol->plid] = pd;
264− pd->blkg = blkg;
265− pol->ops.blkio_init_group_fn(blkg);
266−}
267−EXPORT_SYMBOL_GPL(update_root_blkg_pd);
268−
269249 /**
270250 * blkg_destroy_all - destroy all blkgs associated with a request_queue
271251 * @q: request_queue of interest
@@ -339,7 +319,8 @@ blkiocg_reset_stats(struct cgroup *cgroup, struct cftype *cftype, u64 val) · 67 unmodified lines
339319 for (i = 0; i < BLKCG_MAX_POLS; i++) {
340320 struct blkio_policy_type *pol = blkio_policy[i];
341321
342− if (pol && pol->ops.blkio_reset_group_stats_fn)
322+ if (blkcg_policy_enabled(blkg->q, pol) &&
323+ pol->ops.blkio_reset_group_stats_fn)
343324 pol->ops.blkio_reset_group_stats_fn(blkg);
344325 }
345326 }
@@ -385,7 +366,7 @@ void blkcg_print_blkgs(struct seq_file *sf, struct blkio_cgroup *blkcg, · 39 unmodified lines
385366
386367 spin_lock_irq(&blkcg->lock);
387368 hlist_for_each_entry(blkg, n, &blkcg->blkg_list, blkcg_node)
388− if (blkg->pd[pol->plid])
369+ if (blkcg_policy_enabled(blkg->q, pol))
389370 total += prfill(sf, blkg->pd[pol->plid]->pdata, data);
390371 spin_unlock_irq(&blkcg->lock);
391372
@@ -510,7 +491,10 @@ int blkg_conf_prep(struct blkio_cgroup *blkcg, · 118 unmodified lines
510491 rcu_read_lock();
511492 spin_lock_irq(disk->queue->queue_lock);
512493
513− blkg = blkg_lookup_create(blkcg, disk->queue, false);
494+ if (blkcg_policy_enabled(disk->queue, pol))
495+ blkg = blkg_lookup_create(blkcg, disk->queue, false);
496+ else
497+ blkg = ERR_PTR(-EINVAL);
514498
515499 if (IS_ERR(blkg)) {
516500 ret = PTR_ERR(blkg);
@@ -712,30 +696,6 @@ static int blkiocg_can_attach(struct cgroup *cgrp, struct cgroup_taskset *tset) · 195 unmodified lines
712696 return ret;
713697 }
714698
715−static void blkcg_bypass_start(void)
716− __acquires(&all_q_mutex)
717−{
718− struct request_queue *q;
719−
720− mutex_lock(&all_q_mutex);
721−
722− list_for_each_entry(q, &all_q_list, all_q_node) {
723− blk_queue_bypass_start(q);
724− blkg_destroy_all(q, false);
725− }
726−}
727−
728−static void blkcg_bypass_end(void)
729− __releases(&all_q_mutex)
730−{
731− struct request_queue *q;
732−
733− list_for_each_entry(q, &all_q_list, all_q_node)
734− blk_queue_bypass_end(q);
735−
736− mutex_unlock(&all_q_mutex);
737−}
738−
739699 struct cgroup_subsys blkio_subsys = {
740700 .name = "blkio",
741701 .create = blkiocg_create,
@@ -748,6 +708,139 @@ struct cgroup_subsys blkio_subsys = { · 6 unmodified lines
748708 };
749709 EXPORT_SYMBOL_GPL(blkio_subsys);
750710
711+/**
712+ * blkcg_activate_policy - activate a blkcg policy on a request_queue
713+ * @q: request_queue of interest
714+ * @pol: blkcg policy to activate
715+ *
716+ * Activate @pol on @q. Requires %GFP_KERNEL context. @q goes through
717+ * bypass mode to populate its blkgs with policy_data for @pol.
718+ *
719+ * Activation happens with @q bypassed, so nobody would be accessing blkgs
720+ * from IO path. Update of each blkg is protected by both queue and blkcg
721+ * locks so that holding either lock and testing blkcg_policy_enabled() is
722+ * always enough for dereferencing policy data.
723+ *
724+ * The caller is responsible for synchronizing [de]activations and policy
725+ * [un]registerations. Returns 0 on success, -errno on failure.
726+ */
727+int blkcg_activate_policy(struct request_queue *q,
728+ const struct blkio_policy_type *pol)
729+{
730+ LIST_HEAD(pds);
731+ struct blkio_group *blkg;
732+ struct blkg_policy_data *pd, *n;
733+ int cnt = 0, ret;
734+
735+ if (blkcg_policy_enabled(q, pol))
736+ return 0;
737+
738+ blk_queue_bypass_start(q);
739+
740+ /* make sure the root blkg exists and count the existing blkgs */
741+ spin_lock_irq(q->queue_lock);
742+
743+ rcu_read_lock();
744+ blkg = blkg_lookup_create(&blkio_root_cgroup, q, true);
745+ rcu_read_unlock();
746+
747+ if (IS_ERR(blkg)) {
748+ ret = PTR_ERR(blkg);
749+ goto out_unlock;
750+ }
751+ q->root_blkg = blkg;
752+
753+ list_for_each_entry(blkg, &q->blkg_list, q_node)
754+ cnt++;
755+
756+ spin_unlock_irq(q->queue_lock);
757+
758+ /* allocate policy_data for all existing blkgs */
759+ while (cnt--) {
760+ pd = kzalloc_node(blkg_pd_size(pol), GFP_KERNEL, q->node);
761+ if (!pd) {
762+ ret = -ENOMEM;
763+ goto out_free;
764+ }
765+ list_add_tail(&pd->alloc_node, &pds);
766+ }
767+
768+ /*
769+ * Install the allocated pds. With @q bypassing, no new blkg
770+ * should have been created while the queue lock was dropped.
771+ */
772+ spin_lock_irq(q->queue_lock);
773+
774+ list_for_each_entry(blkg, &q->blkg_list, q_node) {
775+ if (WARN_ON(list_empty(&pds))) {
776+ /* umm... this shouldn't happen, just abort */
777+ ret = -ENOMEM;
778+ goto out_unlock;
779+ }
780+ pd = list_first_entry(&pds, struct blkg_policy_data, alloc_node);
781+ list_del_init(&pd->alloc_node);
782+
783+ /* grab blkcg lock too while installing @pd on @blkg */
784+ spin_lock(&blkg->blkcg->lock);
785+
786+ blkg->pd[pol->plid] = pd;
787+ pd->blkg = blkg;
788+ pol->ops.blkio_init_group_fn(blkg);
789+
790+ spin_unlock(&blkg->blkcg->lock);
791+ }
792+
793+ __set_bit(pol->plid, q->blkcg_pols);
794+ ret = 0;
795+out_unlock:
796+ spin_unlock_irq(q->queue_lock);
797+out_free:
798+ blk_queue_bypass_end(q);
799+ list_for_each_entry_safe(pd, n, &pds, alloc_node)
800+ kfree(pd);
801+ return ret;
802+}
803+EXPORT_SYMBOL_GPL(blkcg_activate_policy);
804+
805+/**
806+ * blkcg_deactivate_policy - deactivate a blkcg policy on a request_queue
807+ * @q: request_queue of interest
808+ * @pol: blkcg policy to deactivate
809+ *
810+ * Deactivate @pol on @q. Follows the same synchronization rules as
811+ * blkcg_activate_policy().
812+ */
813+void blkcg_deactivate_policy(struct request_queue *q,
814+ const struct blkio_policy_type *pol)
815+{
816+ struct blkio_group *blkg;
817+
818+ if (!blkcg_policy_enabled(q, pol))
819+ return;
820+
821+ blk_queue_bypass_start(q);
822+ spin_lock_irq(q->queue_lock);
823+
824+ __clear_bit(pol->plid, q->blkcg_pols);
825+
826+ list_for_each_entry(blkg, &q->blkg_list, q_node) {
827+ /* grab blkcg lock too while removing @pd from @blkg */
828+ spin_lock(&blkg->blkcg->lock);
829+
830+ if (pol->ops.blkio_exit_group_fn)
831+ pol->ops.blkio_exit_group_fn(blkg);
832+
833+ kfree(blkg->pd[pol->plid]);
834+ blkg->pd[pol->plid] = NULL;
835+
836+ spin_unlock(&blkg->blkcg->lock);
837+ }
838+
839+ spin_unlock_irq(q->queue_lock);
840+ blk_queue_bypass_end(q);
841+}
842+EXPORT_SYMBOL_GPL(blkcg_deactivate_policy);
843+
751844 /**
752845 * blkio_policy_register - register a blkcg policy
753846 * @blkiop: blkcg policy to register
@@ -758,7 +851,6 @@ EXPORT_SYMBOL_GPL(blkio_subsys); · 4 unmodified lines
758851 */
759852 int blkio_policy_register(struct blkio_policy_type *blkiop)
760853 {
761− struct request_queue *q;
762854 int i, ret;
763855
764856 mutex_lock(&blkcg_pol_mutex);
@@ -775,11 +867,6 @@ int blkio_policy_register(struct blkio_policy_type *blkiop) · 10 unmodified lines
775867 blkiop->plid = i;
776868 blkio_policy[i] = blkiop;
777869
778− blkcg_bypass_start();
779− list_for_each_entry(q, &all_q_list, all_q_node)
780− update_root_blkg_pd(q, blkiop);
781− blkcg_bypass_end();
782−
783870 /* everything is in place, add intf files for the new policy */
784871 if (blkiop->cftypes)
785872 WARN_ON(cgroup_add_cftypes(&blkio_subsys, blkiop->cftypes));
@@ -798,8 +885,6 @@ EXPORT_SYMBOL_GPL(blkio_policy_register); · 12 unmodified lines
798885 */
799886 void blkio_policy_unregister(struct blkio_policy_type *blkiop)
800887 {
801− struct request_queue *q;
802−
803888 mutex_lock(&blkcg_pol_mutex);
804889
805890 if (WARN_ON(blkio_policy[blkiop->plid] != blkiop))
@@ -811,11 +896,6 @@ void blkio_policy_unregister(struct blkio_policy_type *blkiop) · 5 unmodified lines
811896
812897 /* unregister and update blkgs */
813898 blkio_policy[blkiop->plid] = NULL;
814−
815− blkcg_bypass_start();
816− list_for_each_entry(q, &all_q_list, all_q_node)
817− update_root_blkg_pd(q, blkiop);
818− blkcg_bypass_end();
819899 out_unlock:
820900 mutex_unlock(&blkcg_pol_mutex);
821901 }
block/blk-cgroup.h+11−4
@@ -64,6 +64,9 @@ struct blkg_policy_data { · 63 unmodified lines
6464 /* the blkg this per-policy data belongs to */
6565 struct blkio_group *blkg;
6666
67+ /* used during policy activation */
68+ struct list_head alloc_node;
69+
6770 /* pol->pdata_size bytes of private data used by policy impl */
6871 char pdata[] __aligned(__alignof__(unsigned long long));
6972 };
@@ -108,9 +111,11 @@ extern void blkcg_exit_queue(struct request_queue *q); · 38 unmodified lines
108111 /* Blkio controller policy registration */
109112 extern int blkio_policy_register(struct blkio_policy_type *);
110113 extern void blkio_policy_unregister(struct blkio_policy_type *);
114+extern int blkcg_activate_policy(struct request_queue *q,
115+ const struct blkio_policy_type *pol);
116+extern void blkcg_deactivate_policy(struct request_queue *q,
117+ const struct blkio_policy_type *pol);
111118 extern void blkg_destroy_all(struct request_queue *q, bool destroy_root);
112−extern void update_root_blkg_pd(struct request_queue *q,
113− const struct blkio_policy_type *pol);
114119
115120 void blkcg_print_blkgs(struct seq_file *sf, struct blkio_cgroup *blkcg,
116121 u64 (*prfill)(struct seq_file *, void *, int),
@@ -325,10 +330,12 @@ static inline void blkcg_drain_queue(struct request_queue *q) { } · 208 unmodified lines
325330 static inline void blkcg_exit_queue(struct request_queue *q) { }
326331 static inline int blkio_policy_register(struct blkio_policy_type *blkiop) { return 0; }
327332 static inline void blkio_policy_unregister(struct blkio_policy_type *blkiop) { }
333+static inline int blkcg_activate_policy(struct request_queue *q,
334+ const struct blkio_policy_type *pol) { return 0; }
335+static inline void blkcg_deactivate_policy(struct request_queue *q,
336+ const struct blkio_policy_type *pol) { }
328337 static inline void blkg_destroy_all(struct request_queue *q,
329338 bool destory_root) { }
330−static inline void update_root_blkg_pd(struct request_queue *q,
331− const struct blkio_policy_type *pol) { }
332339
333340 static inline void *blkg_to_pdata(struct blkio_group *blkg,
334341 struct blkio_policy_type *pol) { return NULL; }
block/blk-throttle.c+19−33
@@ -995,35 +995,31 @@ static int tg_set_conf(struct cgroup *cgrp, struct cftype *cft, const char *buf, · 994 unmodified lines
995995 struct blkio_cgroup *blkcg = cgroup_to_blkio_cgroup(cgrp);
996996 struct blkg_conf_ctx ctx;
997997 struct throtl_grp *tg;
998+ struct throtl_data *td;
998999 int ret;
9991000
10001001 ret = blkg_conf_prep(blkcg, &blkio_policy_throtl, buf, &ctx);
10011002 if (ret)
10021003 return ret;
10031004
1004− ret = -EINVAL;
10051005 tg = blkg_to_tg(ctx.blkg);
1006− if (tg) {
1007− struct throtl_data *td = ctx.blkg->q->td;
1008−
1009− if (!ctx.v)
1010− ctx.v = -1;
1006+ td = ctx.blkg->q->td;
10111007
1012− if (is_u64)
1013− *(u64 *)((void *)tg + cft->private) = ctx.v;
1014− else
1015− *(unsigned int *)((void *)tg + cft->private) = ctx.v;
1008+ if (!ctx.v)
1009+ ctx.v = -1;
10161010
1017− /* XXX: we don't need the following deferred processing */
1018− xchg(&tg->limits_changed, true);
1019− xchg(&td->limits_changed, true);
1020− throtl_schedule_delayed_work(td, 0);
1011+ if (is_u64)
1012+ *(u64 *)((void *)tg + cft->private) = ctx.v;
1013+ else
1014+ *(unsigned int *)((void *)tg + cft->private) = ctx.v;
10211015
1022− ret = 0;
1023− }
1016+ /* XXX: we don't need the following deferred processing */
1017+ xchg(&tg->limits_changed, true);
1018+ xchg(&td->limits_changed, true);
1019+ throtl_schedule_delayed_work(td, 0);
10241020
10251021 blkg_conf_finish(&ctx);
1026− return ret;
1022+ return 0;
10271023 }
10281024
10291025 static int tg_set_conf_u64(struct cgroup *cgrp, struct cftype *cft,
@@ -1230,7 +1226,7 @@ void blk_throtl_drain(struct request_queue *q) · 200 unmodified lines
12301226 int blk_throtl_init(struct request_queue *q)
12311227 {
12321228 struct throtl_data *td;
1233− struct blkio_group *blkg;
1229+ int ret;
12341230
12351231 td = kzalloc_node(sizeof(*td), GFP_KERNEL, q->node);
12361232 if (!td)
@@ -1243,28 +1239,18 @@ int blk_throtl_init(struct request_queue *q) · 6 unmodified lines
12431239 q->td = td;
12441240 td->queue = q;
12451241
1246− /* alloc and init root group. */
1247− rcu_read_lock();
1248− spin_lock_irq(q->queue_lock);
1249−
1250− blkg = blkg_lookup_create(&blkio_root_cgroup, q, true);
1251− if (!IS_ERR(blkg))
1252− q->root_blkg = blkg;
1253−
1254− spin_unlock_irq(q->queue_lock);
1255− rcu_read_unlock();
1256−
1257− if (!q->root_blkg) {
1242+ /* activate policy */
1243+ ret = blkcg_activate_policy(q, &blkio_policy_throtl);
1244+ if (ret)
12581245 kfree(td);
1259− return -ENOMEM;
1260− }
1261− return 0;
1246+ return ret;
12621247 }
12631248
12641249 void blk_throtl_exit(struct request_queue *q)
12651250 {
12661251 BUG_ON(!q->td);
12671252 throtl_shutdown_wq(q);
1253+ blkcg_deactivate_policy(q, &blkio_policy_throtl);
12681254 kfree(q->td);
12691255 }
12701256
block/cfq-iosched.c+16−21
@@ -1406,8 +1406,7 @@ static int cfqg_set_weight_device(struct cgroup *cgrp, struct cftype *cft, · 1405 unmodified lines
14061406
14071407 ret = -EINVAL;
14081408 cfqg = blkg_to_cfqg(ctx.blkg);
1409− if (cfqg && (!ctx.v || (ctx.v >= CFQ_WEIGHT_MIN &&
1410− ctx.v <= CFQ_WEIGHT_MAX))) {
1409+ if (!ctx.v || (ctx.v >= CFQ_WEIGHT_MIN && ctx.v <= CFQ_WEIGHT_MAX)) {
14111410 cfqg->dev_weight = ctx.v;
14121411 cfqg->new_weight = cfqg->dev_weight ?: blkcg->cfq_weight;
14131412 ret = 0;
@@ -3938,7 +3937,7 @@ static void cfq_exit_queue(struct elevator_queue *e) · 2524 unmodified lines
39383937 #ifndef CONFIG_CFQ_GROUP_IOSCHED
39393938 kfree(cfqd->root_group);
39403939 #endif
3941− update_root_blkg_pd(q, &blkio_policy_cfq);
3940+ blkcg_deactivate_policy(q, &blkio_policy_cfq);
39423941 kfree(cfqd);
39433942 }
39443943
@@ -3946,7 +3945,7 @@ static int cfq_init_queue(struct request_queue *q) · 1 unmodified line
39463945 {
39473946 struct cfq_data *cfqd;
39483947 struct blkio_group *blkg __maybe_unused;
3949− int i;
3948+ int i, ret;
39503949
39513950 cfqd = kmalloc_node(sizeof(*cfqd), GFP_KERNEL | __GFP_ZERO, q->node);
39523951 if (!cfqd)
@@ -3960,28 +3959,20 @@ static int cfq_init_queue(struct request_queue *q) · 7 unmodified lines
39603959
39613960 /* Init root group and prefer root group over other groups by default */
39623961 #ifdef CONFIG_CFQ_GROUP_IOSCHED
3963− rcu_read_lock();
3964− spin_lock_irq(q->queue_lock);
3965−
3966− blkg = blkg_lookup_create(&blkio_root_cgroup, q, true);
3967− if (!IS_ERR(blkg)) {
3968− q->root_blkg = blkg;
3969− cfqd->root_group = blkg_to_cfqg(blkg);
3970− }
3962+ ret = blkcg_activate_policy(q, &blkio_policy_cfq);
3963+ if (ret)
3964+ goto out_free;
39713965
3972− spin_unlock_irq(q->queue_lock);
3973− rcu_read_unlock();
3966+ cfqd->root_group = blkg_to_cfqg(q->root_blkg);
39743967 #else
3968+ ret = -ENOMEM;
39753969 cfqd->root_group = kzalloc_node(sizeof(*cfqd->root_group),
39763970 GFP_KERNEL, cfqd->queue->node);
3977− if (cfqd->root_group)
3978− cfq_init_cfqg_base(cfqd->root_group);
3979−#endif
3980− if (!cfqd->root_group) {
3981− kfree(cfqd);
3982− return -ENOMEM;
3983− }
3971+ if (!cfqd->root_group)
3972+ goto out_free;
39843973
3974+ cfq_init_cfqg_base(cfqd->root_group);
3975+#endif
39853976 cfqd->root_group->weight = 2 * CFQ_WEIGHT_DEFAULT;
39863977
39873978 /*
@@ -4031,6 +4022,10 @@ static int cfq_init_queue(struct request_queue *q) · 43 unmodified lines
40314022 */
40324023 cfqd->last_delayed_sync = jiffies - HZ;
40334024 return 0;
4025+
4026+out_free:
4027+ kfree(cfqd);
4028+ return ret;
40344029 }
40354030
40364031 /*
block/elevator.c+0−2
@@ -896,8 +896,6 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e) · 895 unmodified lines
896896 ioc_clear_queue(q);
897897 spin_unlock_irq(q->queue_lock);
898898
899− blkg_destroy_all(q, false);
900−
901899 /* allocate, init and register new elevator */
902900 err = -ENOMEM;
903901 q->elevator = elevator_alloc(q, new_e);
include/linux/blkdev.h+1−0
@@ -370,6 +370,7 @@ struct request_queue { · 369 unmodified lines
370370
371371 struct list_head icq_list;
372372 #ifdef CONFIG_BLK_CGROUP
373+ DECLARE_BITMAP (blkcg_pols, BLKCG_MAX_POLS);
373374 struct blkio_group *root_blkg;
374375 struct list_head blkg_list;
375376 #endif

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t