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 533af75329e6..dba52b62cef8 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -895,7 +895,7 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
895 * task has exited, don't wait 895 * task has exited, don't wait
896 */ 896 */
897 cic = cfqd->active_cic; 897 cic = cfqd->active_cic;
898 if (!cic || !cic->ioc->task) 898 if (!cic || !atomic_read(&cic->ioc->nr_tasks))
899 return; 899 return;
900 900
901 /* 901 /*
@@ -1178,6 +1178,8 @@ static void cfq_free_io_context(struct io_context *ioc)
1178 1178
1179 ioc->ioc_data = NULL; 1179 ioc->ioc_data = NULL;
1180 1180
1181 spin_lock(&ioc->lock);
1182
1181 while ((n = rb_first(&ioc->cic_root)) != NULL) { 1183 while ((n = rb_first(&ioc->cic_root)) != NULL) {
1182 __cic = rb_entry(n, struct cfq_io_context, rb_node); 1184 __cic = rb_entry(n, struct cfq_io_context, rb_node);
1183 rb_erase(&__cic->rb_node, &ioc->cic_root); 1185 rb_erase(&__cic->rb_node, &ioc->cic_root);
@@ -1189,6 +1191,8 @@ static void cfq_free_io_context(struct io_context *ioc)
1189 1191
1190 if (ioc_gone && !elv_ioc_count_read(ioc_count)) 1192 if (ioc_gone && !elv_ioc_count_read(ioc_count))
1191 complete(ioc_gone); 1193 complete(ioc_gone);
1194
1195 spin_unlock(&ioc->lock);
1192} 1196}
1193 1197
1194static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq) 1198static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq)
@@ -1243,6 +1247,7 @@ static void cfq_exit_io_context(struct io_context *ioc)
1243 1247
1244 ioc->ioc_data = NULL; 1248 ioc->ioc_data = NULL;
1245 1249
1250 spin_lock(&ioc->lock);
1246 /* 1251 /*
1247 * put the reference this task is holding to the various queues 1252 * put the reference this task is holding to the various queues
1248 */ 1253 */
@@ -1253,6 +1258,8 @@ static void cfq_exit_io_context(struct io_context *ioc)
1253 cfq_exit_single_io_context(__cic); 1258 cfq_exit_single_io_context(__cic);
1254 n = rb_next(n); 1259 n = rb_next(n);
1255 } 1260 }
1261
1262 spin_unlock(&ioc->lock);
1256} 1263}
1257 1264
1258static struct cfq_io_context * 1265static struct cfq_io_context *
@@ -1349,6 +1356,8 @@ static void cfq_ioc_set_ioprio(struct io_context *ioc)
1349 struct cfq_io_context *cic; 1356 struct cfq_io_context *cic;
1350 struct rb_node *n; 1357 struct rb_node *n;
1351 1358
1359 spin_lock(&ioc->lock);
1360
1352 ioc->ioprio_changed = 0; 1361 ioc->ioprio_changed = 0;
1353 1362
1354 n = rb_first(&ioc->cic_root); 1363 n = rb_first(&ioc->cic_root);
@@ -1358,6 +1367,8 @@ static void cfq_ioc_set_ioprio(struct io_context *ioc)
1358 changed_ioprio(cic); 1367 changed_ioprio(cic);
1359 n = rb_next(n); 1368 n = rb_next(n);
1360 } 1369 }
1370
1371 spin_unlock(&ioc->lock);
1361} 1372}
1362 1373
1363static struct cfq_queue * 1374static struct cfq_queue *
@@ -1502,6 +1513,7 @@ cfq_cic_rb_lookup(struct cfq_data *cfqd, struct io_context *ioc)
1502 if (cic && cic->key == cfqd) 1513 if (cic && cic->key == cfqd)
1503 return cic; 1514 return cic;
1504 1515
1516 spin_lock(&ioc->lock);
1505restart: 1517restart:
1506 n = ioc->cic_root.rb_node; 1518 n = ioc->cic_root.rb_node;
1507 while (n) { 1519 while (n) {
@@ -1519,10 +1531,12 @@ restart:
1519 n = n->rb_right; 1531 n = n->rb_right;
1520 else { 1532 else {
1521 ioc->ioc_data = cic; 1533 ioc->ioc_data = cic;
1534 spin_unlock(&ioc->lock);
1522 return cic; 1535 return cic;
1523 } 1536 }
1524 } 1537 }
1525 1538
1539 spin_unlock(&ioc->lock);
1526 return NULL; 1540 return NULL;
1527} 1541}
1528 1542
@@ -1536,6 +1550,7 @@ cfq_cic_link(struct cfq_data *cfqd, struct io_context *ioc,
1536 unsigned long flags; 1550 unsigned long flags;
1537 void *k; 1551 void *k;
1538 1552
1553 spin_lock(&ioc->lock);
1539 cic->ioc = ioc; 1554 cic->ioc = ioc;
1540 cic->key = cfqd; 1555 cic->key = cfqd;
1541 1556
@@ -1566,6 +1581,7 @@ restart:
1566 spin_lock_irqsave(cfqd->queue->queue_lock, flags); 1581 spin_lock_irqsave(cfqd->queue->queue_lock, flags);
1567 list_add(&cic->queue_list, &cfqd->cic_list); 1582 list_add(&cic->queue_list, &cfqd->cic_list);
1568 spin_unlock_irqrestore(cfqd->queue->queue_lock, flags); 1583 spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
1584 spin_unlock(&ioc->lock);
1569} 1585}
1570 1586
1571/* 1587/*
@@ -1659,7 +1675,7 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq,
1659 1675
1660 enable_idle = cfq_cfqq_idle_window(cfqq); 1676 enable_idle = cfq_cfqq_idle_window(cfqq);
1661 1677
1662 if (!cic->ioc->task || !cfqd->cfq_slice_idle || 1678 if (!atomic_read(&cic->ioc->nr_tasks) || !cfqd->cfq_slice_idle ||
1663 (cfqd->hw_tag && CIC_SEEKY(cic))) 1679 (cfqd->hw_tag && CIC_SEEKY(cic)))
1664 enable_idle = 0; 1680 enable_idle = 0;
1665 else if (sample_valid(cic->ttime_samples)) { 1681 else if (sample_valid(cic->ttime_samples)) {