diff options
| -rw-r--r-- | block/cfq-iosched.c | 20 | 
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 | |||
| 1415 | cfq_drop_dead_cic(struct io_context *ioc, struct cfq_io_context *cic) | 1418 | cfq_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 | |||
| 1433 | restart: | 1447 | restart: | 
| 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; | 
