aboutsummaryrefslogtreecommitdiffstats
path: root/block/cfq-iosched.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/cfq-iosched.c')
-rw-r--r--block/cfq-iosched.c66
1 files changed, 33 insertions, 33 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 0f962ecae91f..f4e1006c253d 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -1143,24 +1143,37 @@ static void cfq_put_queue(struct cfq_queue *cfqq)
1143} 1143}
1144 1144
1145/* 1145/*
1146 * Call func for each cic attached to this ioc. Returns number of cic's seen. 1146 * Call func for each cic attached to this ioc.
1147 */ 1147 */
1148static unsigned int 1148static void
1149call_for_each_cic(struct io_context *ioc, 1149call_for_each_cic(struct io_context *ioc,
1150 void (*func)(struct io_context *, struct cfq_io_context *)) 1150 void (*func)(struct io_context *, struct cfq_io_context *))
1151{ 1151{
1152 struct cfq_io_context *cic; 1152 struct cfq_io_context *cic;
1153 struct hlist_node *n; 1153 struct hlist_node *n;
1154 int called = 0;
1155 1154
1156 rcu_read_lock(); 1155 rcu_read_lock();
1157 hlist_for_each_entry_rcu(cic, n, &ioc->cic_list, cic_list) { 1156 hlist_for_each_entry_rcu(cic, n, &ioc->cic_list, cic_list)
1158 func(ioc, cic); 1157 func(ioc, cic);
1159 called++;
1160 }
1161 rcu_read_unlock(); 1158 rcu_read_unlock();
1159}
1160
1161static void cfq_cic_free_rcu(struct rcu_head *head)
1162{
1163 struct cfq_io_context *cic;
1164
1165 cic = container_of(head, struct cfq_io_context, rcu_head);
1166
1167 kmem_cache_free(cfq_ioc_pool, cic);
1168 elv_ioc_count_dec(ioc_count);
1162 1169
1163 return called; 1170 if (ioc_gone && !elv_ioc_count_read(ioc_count))
1171 complete(ioc_gone);
1172}
1173
1174static void cfq_cic_free(struct cfq_io_context *cic)
1175{
1176 call_rcu(&cic->rcu_head, cfq_cic_free_rcu);
1164} 1177}
1165 1178
1166static void cic_free_func(struct io_context *ioc, struct cfq_io_context *cic) 1179static void cic_free_func(struct io_context *ioc, struct cfq_io_context *cic)
@@ -1174,24 +1187,18 @@ static void cic_free_func(struct io_context *ioc, struct cfq_io_context *cic)
1174 hlist_del_rcu(&cic->cic_list); 1187 hlist_del_rcu(&cic->cic_list);
1175 spin_unlock_irqrestore(&ioc->lock, flags); 1188 spin_unlock_irqrestore(&ioc->lock, flags);
1176 1189
1177 kmem_cache_free(cfq_ioc_pool, cic); 1190 cfq_cic_free(cic);
1178} 1191}
1179 1192
1180static void cfq_free_io_context(struct io_context *ioc) 1193static void cfq_free_io_context(struct io_context *ioc)
1181{ 1194{
1182 int freed;
1183
1184 /* 1195 /*
1185 * ioc->refcount is zero here, so no more cic's are allowed to be 1196 * ioc->refcount is zero here, or we are called from elv_unregister(),
1186 * linked into this ioc. So it should be ok to iterate over the known 1197 * so no more cic's are allowed to be linked into this ioc. So it
1187 * list, we will see all cic's since no new ones are added. 1198 * should be ok to iterate over the known list, we will see all cic's
1199 * since no new ones are added.
1188 */ 1200 */
1189 freed = call_for_each_cic(ioc, cic_free_func); 1201 call_for_each_cic(ioc, cic_free_func);
1190
1191 elv_ioc_count_mod(ioc_count, -freed);
1192
1193 if (ioc_gone && !elv_ioc_count_read(ioc_count))
1194 complete(ioc_gone);
1195} 1202}
1196 1203
1197static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq) 1204static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq)
@@ -1207,6 +1214,8 @@ static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq)
1207static void __cfq_exit_single_io_context(struct cfq_data *cfqd, 1214static void __cfq_exit_single_io_context(struct cfq_data *cfqd,
1208 struct cfq_io_context *cic) 1215 struct cfq_io_context *cic)
1209{ 1216{
1217 struct io_context *ioc = cic->ioc;
1218
1210 list_del_init(&cic->queue_list); 1219 list_del_init(&cic->queue_list);
1211 1220
1212 /* 1221 /*
@@ -1216,6 +1225,9 @@ static void __cfq_exit_single_io_context(struct cfq_data *cfqd,
1216 cic->dead_key = (unsigned long) cic->key; 1225 cic->dead_key = (unsigned long) cic->key;
1217 cic->key = NULL; 1226 cic->key = NULL;
1218 1227
1228 if (ioc->ioc_data == cic)
1229 rcu_assign_pointer(ioc->ioc_data, NULL);
1230
1219 if (cic->cfqq[ASYNC]) { 1231 if (cic->cfqq[ASYNC]) {
1220 cfq_exit_cfqq(cfqd, cic->cfqq[ASYNC]); 1232 cfq_exit_cfqq(cfqd, cic->cfqq[ASYNC]);
1221 cic->cfqq[ASYNC] = NULL; 1233 cic->cfqq[ASYNC] = NULL;
@@ -1248,7 +1260,6 @@ static void cfq_exit_single_io_context(struct io_context *ioc,
1248 */ 1260 */
1249static void cfq_exit_io_context(struct io_context *ioc) 1261static void cfq_exit_io_context(struct io_context *ioc)
1250{ 1262{
1251 rcu_assign_pointer(ioc->ioc_data, NULL);
1252 call_for_each_cic(ioc, cfq_exit_single_io_context); 1263 call_for_each_cic(ioc, cfq_exit_single_io_context);
1253} 1264}
1254 1265
@@ -1458,15 +1469,6 @@ cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct io_context *ioc,
1458 return cfqq; 1469 return cfqq;
1459} 1470}
1460 1471
1461static void cfq_cic_free(struct cfq_io_context *cic)
1462{
1463 kmem_cache_free(cfq_ioc_pool, cic);
1464 elv_ioc_count_dec(ioc_count);
1465
1466 if (ioc_gone && !elv_ioc_count_read(ioc_count))
1467 complete(ioc_gone);
1468}
1469
1470/* 1472/*
1471 * We drop cfq io contexts lazily, so we may find a dead one. 1473 * We drop cfq io contexts lazily, so we may find a dead one.
1472 */ 1474 */
@@ -1480,8 +1482,7 @@ cfq_drop_dead_cic(struct cfq_data *cfqd, struct io_context *ioc,
1480 1482
1481 spin_lock_irqsave(&ioc->lock, flags); 1483 spin_lock_irqsave(&ioc->lock, flags);
1482 1484
1483 if (ioc->ioc_data == cic) 1485 BUG_ON(ioc->ioc_data == cic);
1484 rcu_assign_pointer(ioc->ioc_data, NULL);
1485 1486
1486 radix_tree_delete(&ioc->radix_root, (unsigned long) cfqd); 1487 radix_tree_delete(&ioc->radix_root, (unsigned long) cfqd);
1487 hlist_del_rcu(&cic->cic_list); 1488 hlist_del_rcu(&cic->cic_list);
@@ -2138,7 +2139,7 @@ static int __init cfq_slab_setup(void)
2138 if (!cfq_pool) 2139 if (!cfq_pool)
2139 goto fail; 2140 goto fail;
2140 2141
2141 cfq_ioc_pool = KMEM_CACHE(cfq_io_context, SLAB_DESTROY_BY_RCU); 2142 cfq_ioc_pool = KMEM_CACHE(cfq_io_context, 0);
2142 if (!cfq_ioc_pool) 2143 if (!cfq_ioc_pool)
2143 goto fail; 2144 goto fail;
2144 2145
@@ -2286,7 +2287,6 @@ static void __exit cfq_exit(void)
2286 smp_wmb(); 2287 smp_wmb();
2287 if (elv_ioc_count_read(ioc_count)) 2288 if (elv_ioc_count_read(ioc_count))
2288 wait_for_completion(ioc_gone); 2289 wait_for_completion(ioc_gone);
2289 synchronize_rcu();
2290 cfq_slab_kill(); 2290 cfq_slab_kill();
2291} 2291}
2292 2292