diff options
-rw-r--r-- | block/as-iosched.c | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/block/as-iosched.c b/block/as-iosched.c index cb5e53b05c7c..b201d16a7102 100644 --- a/block/as-iosched.c +++ b/block/as-iosched.c | |||
@@ -170,9 +170,11 @@ static void free_as_io_context(struct as_io_context *aic) | |||
170 | 170 | ||
171 | static void as_trim(struct io_context *ioc) | 171 | static void as_trim(struct io_context *ioc) |
172 | { | 172 | { |
173 | spin_lock(&ioc->lock); | ||
173 | if (ioc->aic) | 174 | if (ioc->aic) |
174 | free_as_io_context(ioc->aic); | 175 | free_as_io_context(ioc->aic); |
175 | ioc->aic = NULL; | 176 | ioc->aic = NULL; |
177 | spin_unlock(&ioc->lock); | ||
176 | } | 178 | } |
177 | 179 | ||
178 | /* Called when the task exits */ | 180 | /* Called when the task exits */ |
@@ -462,7 +464,9 @@ static void as_antic_timeout(unsigned long data) | |||
462 | spin_lock_irqsave(q->queue_lock, flags); | 464 | spin_lock_irqsave(q->queue_lock, flags); |
463 | if (ad->antic_status == ANTIC_WAIT_REQ | 465 | if (ad->antic_status == ANTIC_WAIT_REQ |
464 | || ad->antic_status == ANTIC_WAIT_NEXT) { | 466 | || ad->antic_status == ANTIC_WAIT_NEXT) { |
465 | struct as_io_context *aic = ad->io_context->aic; | 467 | struct as_io_context *aic; |
468 | spin_lock(&ad->io_context->lock); | ||
469 | aic = ad->io_context->aic; | ||
466 | 470 | ||
467 | ad->antic_status = ANTIC_FINISHED; | 471 | ad->antic_status = ANTIC_FINISHED; |
468 | kblockd_schedule_work(&ad->antic_work); | 472 | kblockd_schedule_work(&ad->antic_work); |
@@ -475,6 +479,7 @@ static void as_antic_timeout(unsigned long data) | |||
475 | /* process not "saved" by a cooperating request */ | 479 | /* process not "saved" by a cooperating request */ |
476 | ad->exit_no_coop = (7*ad->exit_no_coop + 256)/8; | 480 | ad->exit_no_coop = (7*ad->exit_no_coop + 256)/8; |
477 | } | 481 | } |
482 | spin_unlock(&ad->io_context->lock); | ||
478 | } | 483 | } |
479 | spin_unlock_irqrestore(q->queue_lock, flags); | 484 | spin_unlock_irqrestore(q->queue_lock, flags); |
480 | } | 485 | } |
@@ -635,9 +640,11 @@ static int as_can_break_anticipation(struct as_data *ad, struct request *rq) | |||
635 | 640 | ||
636 | ioc = ad->io_context; | 641 | ioc = ad->io_context; |
637 | BUG_ON(!ioc); | 642 | BUG_ON(!ioc); |
643 | spin_lock(&ioc->lock); | ||
638 | 644 | ||
639 | if (rq && ioc == RQ_IOC(rq)) { | 645 | if (rq && ioc == RQ_IOC(rq)) { |
640 | /* request from same process */ | 646 | /* request from same process */ |
647 | spin_unlock(&ioc->lock); | ||
641 | return 1; | 648 | return 1; |
642 | } | 649 | } |
643 | 650 | ||
@@ -646,20 +653,25 @@ static int as_can_break_anticipation(struct as_data *ad, struct request *rq) | |||
646 | * In this situation status should really be FINISHED, | 653 | * In this situation status should really be FINISHED, |
647 | * however the timer hasn't had the chance to run yet. | 654 | * however the timer hasn't had the chance to run yet. |
648 | */ | 655 | */ |
656 | spin_unlock(&ioc->lock); | ||
649 | return 1; | 657 | return 1; |
650 | } | 658 | } |
651 | 659 | ||
652 | aic = ioc->aic; | 660 | aic = ioc->aic; |
653 | if (!aic) | 661 | if (!aic) { |
662 | spin_unlock(&ioc->lock); | ||
654 | return 0; | 663 | return 0; |
664 | } | ||
655 | 665 | ||
656 | if (atomic_read(&aic->nr_queued) > 0) { | 666 | if (atomic_read(&aic->nr_queued) > 0) { |
657 | /* process has more requests queued */ | 667 | /* process has more requests queued */ |
668 | spin_unlock(&ioc->lock); | ||
658 | return 1; | 669 | return 1; |
659 | } | 670 | } |
660 | 671 | ||
661 | if (atomic_read(&aic->nr_dispatched) > 0) { | 672 | if (atomic_read(&aic->nr_dispatched) > 0) { |
662 | /* process has more requests dispatched */ | 673 | /* process has more requests dispatched */ |
674 | spin_unlock(&ioc->lock); | ||
663 | return 1; | 675 | return 1; |
664 | } | 676 | } |
665 | 677 | ||
@@ -680,6 +692,7 @@ static int as_can_break_anticipation(struct as_data *ad, struct request *rq) | |||
680 | } | 692 | } |
681 | 693 | ||
682 | as_update_iohist(ad, aic, rq); | 694 | as_update_iohist(ad, aic, rq); |
695 | spin_unlock(&ioc->lock); | ||
683 | return 1; | 696 | return 1; |
684 | } | 697 | } |
685 | 698 | ||
@@ -688,20 +701,27 @@ static int as_can_break_anticipation(struct as_data *ad, struct request *rq) | |||
688 | if (aic->ttime_samples == 0) | 701 | if (aic->ttime_samples == 0) |
689 | ad->exit_prob = (7*ad->exit_prob + 256)/8; | 702 | ad->exit_prob = (7*ad->exit_prob + 256)/8; |
690 | 703 | ||
691 | if (ad->exit_no_coop > 128) | 704 | if (ad->exit_no_coop > 128) { |
705 | spin_unlock(&ioc->lock); | ||
692 | return 1; | 706 | return 1; |
707 | } | ||
693 | } | 708 | } |
694 | 709 | ||
695 | if (aic->ttime_samples == 0) { | 710 | if (aic->ttime_samples == 0) { |
696 | if (ad->new_ttime_mean > ad->antic_expire) | 711 | if (ad->new_ttime_mean > ad->antic_expire) { |
712 | spin_unlock(&ioc->lock); | ||
697 | return 1; | 713 | return 1; |
698 | if (ad->exit_prob * ad->exit_no_coop > 128*256) | 714 | } |
715 | if (ad->exit_prob * ad->exit_no_coop > 128*256) { | ||
716 | spin_unlock(&ioc->lock); | ||
699 | return 1; | 717 | return 1; |
718 | } | ||
700 | } else if (aic->ttime_mean > ad->antic_expire) { | 719 | } else if (aic->ttime_mean > ad->antic_expire) { |
701 | /* the process thinks too much between requests */ | 720 | /* the process thinks too much between requests */ |
721 | spin_unlock(&ioc->lock); | ||
702 | return 1; | 722 | return 1; |
703 | } | 723 | } |
704 | 724 | spin_unlock(&ioc->lock); | |
705 | return 0; | 725 | return 0; |
706 | } | 726 | } |
707 | 727 | ||
@@ -1255,7 +1275,9 @@ static void as_merged_requests(struct request_queue *q, struct request *req, | |||
1255 | * Don't copy here but swap, because when anext is | 1275 | * Don't copy here but swap, because when anext is |
1256 | * removed below, it must contain the unused context | 1276 | * removed below, it must contain the unused context |
1257 | */ | 1277 | */ |
1278 | double_spin_lock(&rioc->lock, &nioc->lock, rioc < nioc); | ||
1258 | swap_io_context(&rioc, &nioc); | 1279 | swap_io_context(&rioc, &nioc); |
1280 | double_spin_unlock(&rioc->lock, &nioc->lock, rioc < nioc); | ||
1259 | } | 1281 | } |
1260 | } | 1282 | } |
1261 | 1283 | ||