aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
Diffstat (limited to 'block')
-rw-r--r--block/cfq-iosched.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 94f53a1f4677..64df3fa303b0 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -1165,6 +1165,8 @@ static void cfq_free_io_context(struct io_context *ioc)
1165 struct rb_node *n; 1165 struct rb_node *n;
1166 int freed = 0; 1166 int freed = 0;
1167 1167
1168 ioc->ioc_data = NULL;
1169
1168 while ((n = rb_first(&ioc->cic_root)) != NULL) { 1170 while ((n = rb_first(&ioc->cic_root)) != NULL) {
1169 __cic = rb_entry(n, struct cfq_io_context, rb_node); 1171 __cic = rb_entry(n, struct cfq_io_context, rb_node);
1170 rb_erase(&__cic->rb_node, &ioc->cic_root); 1172 rb_erase(&__cic->rb_node, &ioc->cic_root);
@@ -1228,10 +1230,11 @@ static void cfq_exit_io_context(struct io_context *ioc)
1228 struct cfq_io_context *__cic; 1230 struct cfq_io_context *__cic;
1229 struct rb_node *n; 1231 struct rb_node *n;
1230 1232
1233 ioc->ioc_data = NULL;
1234
1231 /* 1235 /*
1232 * put the reference this task is holding to the various queues 1236 * put the reference this task is holding to the various queues
1233 */ 1237 */
1234
1235 n = rb_first(&ioc->cic_root); 1238 n = rb_first(&ioc->cic_root);
1236 while (n != NULL) { 1239 while (n != NULL) {
1237 __cic = rb_entry(n, struct cfq_io_context, rb_node); 1240 __cic = rb_entry(n, struct cfq_io_context, rb_node);
@@ -1415,6 +1418,10 @@ static void
1415cfq_drop_dead_cic(struct io_context *ioc, struct cfq_io_context *cic) 1418cfq_drop_dead_cic(struct io_context *ioc, struct cfq_io_context *cic)
1416{ 1419{
1417 WARN_ON(!list_empty(&cic->queue_list)); 1420 WARN_ON(!list_empty(&cic->queue_list));
1421
1422 if (ioc->ioc_data == cic)
1423 ioc->ioc_data = NULL;
1424
1418 rb_erase(&cic->rb_node, &ioc->cic_root); 1425 rb_erase(&cic->rb_node, &ioc->cic_root);
1419 kmem_cache_free(cfq_ioc_pool, cic); 1426 kmem_cache_free(cfq_ioc_pool, cic);
1420 elv_ioc_count_dec(ioc_count); 1427 elv_ioc_count_dec(ioc_count);
@@ -1430,6 +1437,13 @@ cfq_cic_rb_lookup(struct cfq_data *cfqd, struct io_context *ioc)
1430 if (unlikely(!ioc)) 1437 if (unlikely(!ioc))
1431 return NULL; 1438 return NULL;
1432 1439
1440 /*
1441 * we maintain a last-hit cache, to avoid browsing over the tree
1442 */
1443 cic = ioc->ioc_data;
1444 if (cic && cic->key == cfqd)
1445 return cic;
1446
1433restart: 1447restart:
1434 n = ioc->cic_root.rb_node; 1448 n = ioc->cic_root.rb_node;
1435 while (n) { 1449 while (n) {
@@ -1445,8 +1459,10 @@ restart:
1445 n = n->rb_left; 1459 n = n->rb_left;
1446 else if (key > k) 1460 else if (key > k)
1447 n = n->rb_right; 1461 n = n->rb_right;
1448 else 1462 else {
1463 ioc->ioc_data = cic;
1449 return cic; 1464 return cic;
1465 }
1450 } 1466 }
1451 1467
1452 return NULL; 1468 return NULL;