aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2009-01-02 10:12:50 -0500
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2009-01-02 10:12:50 -0500
commit201bffa46466b4afdf7d29db8eca3fa5decb39c8 (patch)
tree47e7d85563690547b67748092e587be1f31046b5
parent631de3708d595d153e8a510a3608689290f4c0ed (diff)
ide: use per-device request queue locks (v2)
* Move hack for flush requests from choose_drive() to do_ide_request(). * Add ide_plug_device() helper and convert core IDE code from using per-hwgroup lock as a request lock to use the ->queue_lock instead. * Remove no longer needed: - choose_drive() function - WAKEUP() macro - 'sleeping' flag from ide_hwif_t - 'service_{start,time}' fields from ide_drive_t This patch results in much simpler and more maintainable code (besides being a scalability improvement). v2: * Fixes/improvements based on review from Elias: - take as many requests off the queue as possible - remove now redundant BUG_ON() Cc: Elias Oltmanns <eo@nebensachen.de> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
-rw-r--r--drivers/ide/ide-io.c214
-rw-r--r--drivers/ide/ide-park.c13
-rw-r--r--drivers/ide/ide-probe.c3
-rw-r--r--include/linux/ide.h4
4 files changed, 77 insertions, 157 deletions
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index ab480042757a..bb3248abf47d 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -667,85 +667,10 @@ void ide_stall_queue (ide_drive_t *drive, unsigned long timeout)
667 drive->sleep = timeout + jiffies; 667 drive->sleep = timeout + jiffies;
668 drive->dev_flags |= IDE_DFLAG_SLEEPING; 668 drive->dev_flags |= IDE_DFLAG_SLEEPING;
669} 669}
670
671EXPORT_SYMBOL(ide_stall_queue); 670EXPORT_SYMBOL(ide_stall_queue);
672 671
673#define WAKEUP(drive) ((drive)->service_start + 2 * (drive)->service_time)
674
675/**
676 * choose_drive - select a drive to service
677 * @hwgroup: hardware group to select on
678 *
679 * choose_drive() selects the next drive which will be serviced.
680 * This is necessary because the IDE layer can't issue commands
681 * to both drives on the same cable, unlike SCSI.
682 */
683
684static inline ide_drive_t *choose_drive (ide_hwgroup_t *hwgroup)
685{
686 ide_drive_t *drive, *best;
687
688repeat:
689 best = NULL;
690 drive = hwgroup->drive;
691
692 /*
693 * drive is doing pre-flush, ordered write, post-flush sequence. even
694 * though that is 3 requests, it must be seen as a single transaction.
695 * we must not preempt this drive until that is complete
696 */
697 if (blk_queue_flushing(drive->queue)) {
698 /*
699 * small race where queue could get replugged during
700 * the 3-request flush cycle, just yank the plug since
701 * we want it to finish asap
702 */
703 blk_remove_plug(drive->queue);
704 return drive;
705 }
706
707 do {
708 u8 dev_s = !!(drive->dev_flags & IDE_DFLAG_SLEEPING);
709 u8 best_s = (best && !!(best->dev_flags & IDE_DFLAG_SLEEPING));
710
711 if ((dev_s == 0 || time_after_eq(jiffies, drive->sleep)) &&
712 !elv_queue_empty(drive->queue)) {
713 if (best == NULL ||
714 (dev_s && (best_s == 0 || time_before(drive->sleep, best->sleep))) ||
715 (best_s == 0 && time_before(WAKEUP(drive), WAKEUP(best)))) {
716 if (!blk_queue_plugged(drive->queue))
717 best = drive;
718 }
719 }
720 } while ((drive = drive->next) != hwgroup->drive);
721
722 if (best && (best->dev_flags & IDE_DFLAG_NICE1) &&
723 (best->dev_flags & IDE_DFLAG_SLEEPING) == 0 &&
724 best != hwgroup->drive && best->service_time > WAIT_MIN_SLEEP) {
725 long t = (signed long)(WAKEUP(best) - jiffies);
726 if (t >= WAIT_MIN_SLEEP) {
727 /*
728 * We *may* have some time to spare, but first let's see if
729 * someone can potentially benefit from our nice mood today..
730 */
731 drive = best->next;
732 do {
733 if ((drive->dev_flags & IDE_DFLAG_SLEEPING) == 0
734 && time_before(jiffies - best->service_time, WAKEUP(drive))
735 && time_before(WAKEUP(drive), jiffies + t))
736 {
737 ide_stall_queue(best, min_t(long, t, 10 * WAIT_MIN_SLEEP));
738 goto repeat;
739 }
740 } while ((drive = drive->next) != best);
741 }
742 }
743 return best;
744}
745
746/* 672/*
747 * Issue a new request to a drive from hwgroup 673 * Issue a new request to a drive from hwgroup
748 * Caller must have already done spin_lock_irqsave(&hwgroup->lock, ..);
749 * 674 *
750 * A hwgroup is a serialized group of IDE interfaces. Usually there is 675 * A hwgroup is a serialized group of IDE interfaces. Usually there is
751 * exactly one hwif (interface) per hwgroup, but buggy controllers (eg. CMD640) 676 * exactly one hwif (interface) per hwgroup, but buggy controllers (eg. CMD640)
@@ -757,8 +682,7 @@ repeat:
757 * possibly along with many other devices. This is especially common in 682 * possibly along with many other devices. This is especially common in
758 * PCI-based systems with off-board IDE controller cards. 683 * PCI-based systems with off-board IDE controller cards.
759 * 684 *
760 * The IDE driver uses a per-hwgroup spinlock to protect 685 * The IDE driver uses a per-hwgroup lock to protect the hwgroup->busy flag.
761 * access to the request queues, and to protect the hwgroup->busy flag.
762 * 686 *
763 * The first thread into the driver for a particular hwgroup sets the 687 * The first thread into the driver for a particular hwgroup sets the
764 * hwgroup->busy flag to indicate that this hwgroup is now active, 688 * hwgroup->busy flag to indicate that this hwgroup is now active,
@@ -780,61 +704,38 @@ repeat:
780 */ 704 */
781void do_ide_request(struct request_queue *q) 705void do_ide_request(struct request_queue *q)
782{ 706{
783 ide_drive_t *orig_drive = q->queuedata; 707 ide_drive_t *drive = q->queuedata;
784 ide_hwgroup_t *hwgroup = orig_drive->hwif->hwgroup; 708 ide_hwif_t *hwif = drive->hwif;
785 ide_drive_t *drive; 709 ide_hwgroup_t *hwgroup = hwif->hwgroup;
786 ide_hwif_t *hwif;
787 struct request *rq; 710 struct request *rq;
788 ide_startstop_t startstop; 711 ide_startstop_t startstop;
789 712
790 /* caller must own hwgroup->lock */ 713 /*
791 BUG_ON(!irqs_disabled()); 714 * drive is doing pre-flush, ordered write, post-flush sequence. even
792 715 * though that is 3 requests, it must be seen as a single transaction.
793 while (!ide_lock_hwgroup(hwgroup)) { 716 * we must not preempt this drive until that is complete
794 drive = choose_drive(hwgroup); 717 */
795 if (drive == NULL) { 718 if (blk_queue_flushing(q))
796 int sleeping = 0;
797 unsigned long sleep = 0; /* shut up, gcc */
798 hwgroup->rq = NULL;
799 drive = hwgroup->drive;
800 do {
801 if ((drive->dev_flags & IDE_DFLAG_SLEEPING) &&
802 (sleeping == 0 ||
803 time_before(drive->sleep, sleep))) {
804 sleeping = 1;
805 sleep = drive->sleep;
806 }
807 } while ((drive = drive->next) != hwgroup->drive);
808 if (sleeping) {
809 /* 719 /*
810 * Take a short snooze, and then wake up this hwgroup again. 720 * small race where queue could get replugged during
811 * This gives other hwgroups on the same a chance to 721 * the 3-request flush cycle, just yank the plug since
812 * play fairly with us, just in case there are big differences 722 * we want it to finish asap
813 * in relative throughputs.. don't want to hog the cpu too much.
814 */ 723 */
815 if (time_before(sleep, jiffies + WAIT_MIN_SLEEP)) 724 blk_remove_plug(q);
816 sleep = jiffies + WAIT_MIN_SLEEP;
817#if 1
818 if (timer_pending(&hwgroup->timer))
819 printk(KERN_CRIT "ide_set_handler: timer already active\n");
820#endif
821 /* so that ide_timer_expiry knows what to do */
822 hwgroup->sleeping = 1;
823 hwgroup->req_gen_timer = hwgroup->req_gen;
824 mod_timer(&hwgroup->timer, sleep);
825 /* we purposely leave hwgroup locked
826 * while sleeping */
827 } else
828 ide_unlock_hwgroup(hwgroup);
829 725
830 /* no more work for this hwgroup (for now) */ 726 spin_unlock_irq(q->queue_lock);
831 goto plug_device; 727 spin_lock_irq(&hwgroup->lock);
832 }
833 728
834 if (drive != orig_drive) 729 if (!ide_lock_hwgroup(hwgroup)) {
835 goto plug_device; 730repeat:
731 hwgroup->rq = NULL;
836 732
837 hwif = drive->hwif; 733 if (drive->dev_flags & IDE_DFLAG_SLEEPING) {
734 if (time_before(drive->sleep, jiffies)) {
735 ide_unlock_hwgroup(hwgroup);
736 goto plug_device;
737 }
738 }
838 739
839 if (hwif != hwgroup->hwif) { 740 if (hwif != hwgroup->hwif) {
840 /* 741 /*
@@ -847,16 +748,20 @@ void do_ide_request(struct request_queue *q)
847 hwgroup->hwif = hwif; 748 hwgroup->hwif = hwif;
848 hwgroup->drive = drive; 749 hwgroup->drive = drive;
849 drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED); 750 drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED);
850 drive->service_start = jiffies;
851 751
752 spin_unlock_irq(&hwgroup->lock);
753 spin_lock_irq(q->queue_lock);
852 /* 754 /*
853 * we know that the queue isn't empty, but this can happen 755 * we know that the queue isn't empty, but this can happen