Skip to contentSkip to conversation

IDE TCQ #2

PATCH In review Jens Axboe 2 participants 8 messages Apr 9, 2002 – Apr 10, 2002 Block layer

lore
Share & tools
lore

Jens Axboe

author
#0 lore raw

PATCH 1/1 IDE TCQ #2

Hi,

Version 2 is ready. Changes since last time:

- Check if we are using TCQ before doing BUG() if we encounter a plugged queue in ide_do_request(). If so, we just need to quit. SMP race posted yesterday.

- Clean /proc/ide/hdX/tcq output

- Add queue depth controls in /proc/ide/hdX/setting:

echo "using_tcq:0" > /proc/ide/hdX/setting

will disable TCQ and revert to DMA,

echo "using_tcq:32" > /proc/ide/hdX/setting

will set queue depth to 32, any value in between the two are of course also allowed. The driver will print enable/disable info to the kernel log.

- Include the get_request() starvation from akpm, bump queue size a bit as well.

- Correctly use other depths that none or full.

- Make the current depth and int not atomic_t, access is serialized to it.

- Remove 'unexpected interrupt' warnings at boot

- Cleanup service and interrupt handling

- Make the initial tcq enable much nicer

This make look like a lot of stuff, but the only real bug fixed is the SMP race mentioned yesterday. Rest is just features and cleanup. The code has taken quite a lot of beating, so I'm ready to call this beta and ask for more testers. No malfunctions have been detected here. Stuff to still look out for:

- Don't enable TCQ on both master/slave on a channel! That mode is not supported yet, only enable TCQ on one of them at the time.

- SMP seems to have minor performance regression, performance testing should be UP only for now. Also note that I haven't really done any performance testing yet, just data integrity and stability work.

Enjoy!

drivers/block/ll_rw_blk.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/block/ll_rw_blk.c +7 -5
diff -urN -X /home/axboe/cdrom/exclude /opt/kernel/linux-2.5.8-pre2/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
@@ -857,10 +857,10 @@
 	spin_lock_prefetch(q->queue_lock);
 
 	generic_unplug_device(q);
-	add_wait_queue(&rl->wait, &wait);
+	add_wait_queue_exclusive(&rl->wait, &wait);
 	do {
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		if (rl->count < batch_requests)
+		if (!rl->count)
 			schedule();
 		spin_lock_irq(q->queue_lock);
 		rq = get_request(q, rw);
@@ -1683,9 +1683,11 @@
 	 * Free request slots per queue.
 	 * (Half for reads, half for writes)
 	 */
-	queue_nr_requests = 64;
-	if (total_ram > MB(32))
-		queue_nr_requests = 256;
+	queue_nr_requests = (total_ram >> 8) & ~15;	/* One per quarter-megabyte */
+	if (queue_nr_requests < 32)
+		queue_nr_requests = 32;
+	if (queue_nr_requests > 256)
+		queue_nr_requests = 256;
 
 	/*
 	 * Batch frees according to queue length
drivers/ide/Config.help renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/Config.help +22 -0
diff -urN -X /home/axboe/cdrom/exclude /opt/kernel/linux-2.5.8-pre2/drivers/ide/Config.help linux/drivers/ide/Config.help
@@ -744,6 +744,28 @@
 
   Generally say N here.
 
+CONFIG_BLK_DEV_IDE_TCQ
+  Support for tagged command queueing on ATA disk drives. This enables
+  the IDE layer to have multiple in-flight requests on hardware that
+  supports it. For now this includes the IBM Deskstar series drives,
+  such as the GXP75, 40GV, GXP60, and GXP120 (ie any Deskstar made in
+  the last couple of years).
+
+  If you have such a drive, say Y here.
+
+CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
+  Enabled tagged command queueing unconditionally on drives that report
+  support for it.
+
+  Generally say Y here.
+
+CONFIG_BLK_DEV_IDE_TCQ_DEPTH
+  Maximum size of commands to enable per-drive. Any value between 1
+  and 32 is valid, with 32 being the maxium that the hardware supports.
+
+  You probably just want the default of 32 here. If you enter an invalid
+  number, the default value will be used.
+
 CONFIG_BLK_DEV_IT8172
   Say Y here to support the on-board IDE controller on the Integrated
   Technology Express, Inc. ITE8172 SBC.  Vendor page at
drivers/ide/Config.in renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/Config.in +5 -0
diff -urN -X /home/axboe/cdrom/exclude /opt/kernel/linux-2.5.8-pre2/drivers/ide/Config.in linux/drivers/ide/Config.in
@@ -47,6 +47,11 @@
 	 dep_bool '      Use PCI DMA by default when available' CONFIG_IDEDMA_PCI_AUTO $CONFIG_BLK_DEV_IDEDMA_PCI
          dep_bool '    Enable DMA only for disks ' CONFIG_IDEDMA_ONLYDISK $CONFIG_IDEDMA_PCI_AUTO
 	 define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_PCI
+	 dep_bool '    IDE tagged command queueing' CONFIG_BLK_DEV_IDE_TCQ $CONFIG_BLK_DEV_IDEDMA_PCI
+	   dep_bool '    TCQ on by default' CONFIG_BLK_DEV_IDE_TCQ_DEFAULT $CONFIG_BLK_DEV_IDE_TCQ
+	   if [ $CONFIG_BLK_DEV_IDE_TCQ_DEFAULT != "n" ]; then
+		int '    Default queue depth' CONFIG_BLK_DEV_IDE_TCQ_DEPTH 32
+	   fi
 	 dep_bool '    ATA Work(s) In Progress (EXPERIMENTAL)' CONFIG_IDEDMA_PCI_WIP $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_EXPERIMENTAL
 	 dep_bool '    Good-Bad DMA Model-Firmware (WIP)' CONFIG_IDEDMA_NEW_DRIVE_LISTINGS $CONFIG_IDEDMA_PCI_WIP
 	 dep_bool '    AEC62XX chipset support' CONFIG_BLK_DEV_AEC62XX $CONFIG_BLK_DEV_IDEDMA_PCI
drivers/ide/Makefile renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/Makefile +1 -0
diff -urN -X /home/axboe/cdrom/exclude /opt/kernel/linux-2.5.8-pre2/drivers/ide/Makefile linux/drivers/ide/Makefile
@@ -45,6 +45,7 @@
 ide-obj-$(CONFIG_BLK_DEV_HT6560B)	+= ht6560b.o
 ide-obj-$(CONFIG_BLK_DEV_IDE_ICSIDE)	+= icside.o
 ide-obj-$(CONFIG_BLK_DEV_IDEDMA_PCI)	+= ide-dma.o
+ide-obj-$(CONFIG_BLK_DEV_IDE_TCQ)	+= ide-tcq.o
 ide-obj-$(CONFIG_BLK_DEV_IDEPCI)	+= ide-pci.o
 ide-obj-$(CONFIG_BLK_DEV_ISAPNP)	+= ide-pnp.o
 ide-obj-$(CONFIG_BLK_DEV_IDE_PMAC)	+= ide-pmac.o
drivers/ide/ide-disk.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-disk.c +230 -84

465 lines not on this page · raw message

drivers/ide/ide-dma.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-dma.c +114 -91

337 lines not on this page · raw message

drivers/ide/ide-features.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-features.c +0 -3
diff -urN -X /home/axboe/cdrom/exclude /opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-features.c linux/drivers/ide/ide-features.c
@@ -75,10 +75,7 @@
 char *ide_dmafunc_verbose (ide_dma_action_t dmafunc)
 {
 	switch (dmafunc) {
-		case ide_dma_read:		return("ide_dma_read");
-		case ide_dma_write:		return("ide_dma_write");
 		case ide_dma_begin:		return("ide_dma_begin");
-		case ide_dma_end:		return("ide_dma_end:");
 		case ide_dma_check:		return("ide_dma_check");
 		case ide_dma_on:		return("ide_dma_on");
 		case ide_dma_off:		return("ide_dma_off");
drivers/ide/ide-probe.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-probe.c +17 -2
diff -urN -X /home/axboe/cdrom/exclude /opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-probe.c linux/drivers/ide/ide-probe.c
@@ -189,6 +189,21 @@
 	if (drive->channel->quirkproc)
 		drive->quirk_list = drive->channel->quirkproc(drive);
 
+	/*
+	 * it's an ata drive, build command list
+	 */
+#ifndef CONFIG_BLK_DEV_IDE_TCQ
+	drive->queue_depth = 1;
+#else
+	drive->queue_depth = drive->id->queue_depth + 1;
+	if (drive->queue_depth > CONFIG_BLK_DEV_IDE_TCQ_DEPTH)
+		drive->queue_depth = CONFIG_BLK_DEV_IDE_TCQ_DEPTH;
+	if (drive->queue_depth < 1 || drive->queue_depth > IDE_MAX_TAG)
+		drive->queue_depth = IDE_MAX_TAG;
+#endif
+	if (ide_build_commandlist(drive))
+		goto err_misc;
+
 	return;
 
 err_misc:
@@ -593,10 +608,10 @@
 	blk_queue_max_sectors(q, max_sectors);
 
 	/* IDE DMA can do PRD_ENTRIES number of segments. */
-	blk_queue_max_hw_segments(q, PRD_ENTRIES);
+	blk_queue_max_hw_segments(q, PRD_SEGMENTS);
 
 	/* This is a driver limit and could be eliminated. */
-	blk_queue_max_phys_segments(q, PRD_ENTRIES);
+	blk_queue_max_phys_segments(q, PRD_SEGMENTS);
 }
 
 #if MAX_HWIFS > 1
drivers/ide/ide-taskfile.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-taskfile.c +48 -15

128 lines not on this page · raw message

drivers/ide/ide-tcq.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-tcq.c +590 -0

590 lines not on this page · raw message

drivers/ide/ide.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide.c +202 -13

361 lines not on this page · raw message

drivers/ide/pdc202xx.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/pdc202xx.c +6 -0
diff -urN -X /home/axboe/cdrom/exclude /opt/kernel/linux-2.5.8-pre2/drivers/ide/pdc202xx.c linux/drivers/ide/pdc202xx.c
@@ -1057,6 +1057,12 @@
 		case ide_dma_timeout:
 			if (drive->channel->resetproc != NULL)
 				drive->channel->resetproc(drive);
+		/*
+		 * we cannot support queued operations on promise, so fail to
+		 * to enable it...
+		 */
+		case ide_dma_queued_on:
+			return 1;
 		default:
 			break;
 	}
include/linux/hdreg.h renamed from opt/kernel/linux-2.5.8-pre2/include/linux/hdreg.h +8 -0
diff -urN -X /home/axboe/cdrom/exclude /opt/kernel/linux-2.5.8-pre2/include/linux/hdreg.h linux/include/linux/hdreg.h
@@ -34,6 +34,7 @@
 #define ECC_STAT		0x04	/* Corrected error */
 #define DRQ_STAT		0x08
 #define SEEK_STAT		0x10
+#define SERVICE_STAT		SEEK_STAT
 #define WRERR_STAT		0x20
 #define READY_STAT		0x40
 #define BUSY_STAT		0x80
@@ -50,6 +51,13 @@
 #define ICRC_ERR		0x80	/* new meaning:  CRC error during transfer */
 
 /*
+ * bits of NSECTOR reg
+ */
+#define NSEC_CD			0x1
+#define NSEC_IO			0x2
+#define NSEC_REL		0x4
+
+/*
  * Command Header sizes for IOCTL commands
  *	HDIO_DRIVE_CMD and HDIO_DRIVE_TASK
  */
include/linux/ide.h renamed from opt/kernel/linux-2.5.8-pre2/include/linux/ide.h +180 -10

301 lines not on this page · raw message

Signature · 1 line
Jens Axboe
#1 lore raw

Hello.

Since I have been experimenting with your initial release yerstoday, please allow me some more detailed notes about the code:

Quoted 9 lines

echo "using_tcq:0" > /proc/ide/hdX/setting

will disable TCQ and revert to DMA,

echo "using_tcq:32" > /proc/ide/hdX/setting

will set queue depth to 32, any value in between the two are of course also allowed. The driver will print enable/disable info to the kernel log.

Well this belongs to an ioctl or sysctl... However most of the /proc/ide stuff if not all will go to the sysctl quite soon.

Quoted 18 lines

diff -urN -X /home/axboe/cdrom/exclude /opt/kernel/linux-2.5.8-pre2/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c

drivers/block/ll_rw_blk.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/block/ll_rw_blk.c +2 -2
@@ -857,10 +857,10 @@
 	spin_lock_prefetch(q->queue_lock);
 
 	generic_unplug_device(q);
-	add_wait_queue(&rl->wait, &wait);
+	add_wait_queue_exclusive(&rl->wait, &wait);
 	do {
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		if (rl->count < batch_requests)
+		if (!rl->count)
 			schedule();
 		spin_lock_irq(q->queue_lock);
 		rq = get_request(q, rw);
@@ -1683,9 +1683,11 @@
 	 * Free request slots per queue.

drivers/block/ll_rw_blk.c line 1690

Quoted 10 lines
drivers/block/ll_rw_blk.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/block/ll_rw_blk.c +5 -3
 	 * (Half for reads, half for writes)
 	 */
-	queue_nr_requests = 64;
-	if (total_ram > MB(32))
-		queue_nr_requests = 256;
+	queue_nr_requests = (total_ram >> 8) & ~15;	/* One per quarter-megabyte */
+	if (queue_nr_requests < 32)
+		queue_nr_requests = 32;
+	if (queue_nr_requests > 256)
+		queue_nr_requests = 256;

This adaptive behaviour seems to be better fitting possible ram sized those days indeed.

Quoted 16 lines

diff -urN -X /home/axboe/cdrom/exclude /opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c

drivers/ide/ide-disk.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-disk.c +2 -1
@@ -26,9 +26,10 @@
  * Version 1.11		Highmem I/O support, Jens Axboe <[email protected]>
  * Version 1.12		added 48-bit lba
  * Version 1.13		adding taskfile io access method
+ * Version 1.14		Added tcq support, Jens Axboe <[email protected]>
  */
 
-#define IDEDISK_VERSION	"1.13"
+#define IDEDISK_VERSION	"1.14"
 
 #include <linux/config.h>
 #include <linux/module.h>

drivers/ide/ide-disk.c line 113

Quoted 4 lines
drivers/ide/ide-disk.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-disk.c +1 -0
@@ -109,53 +110,64 @@
 static u8 get_command(ide_drive_t *drive, int cmd)
 {
 	int lba48bit = (drive->id->cfs_enable_2 & 0x0400) ? 1 : 0;
+	int command = WIN_NOP;

The "incremental" usage of the command variable I think is an overoptimization. u8 is the proper type for it anyway. I have unwound the code below once to make it more obvious and you would be surprised what GCC does with it :-).

drivers/ide/ide-disk.c line 162

Quoted 3 lines
drivers/ide/ide-disk.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-disk.c +2 -0
+
+	return command;
 }

See you are returning an int entity as u8!

drivers/ide/ide-disk.c line 118

Quoted 2 lines
drivers/ide/ide-disk.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-disk.c +2 -0
+	ide_task_t			*args = &ar->ar_task;
+	struct request			*rq = ar->ar_rq;

Hints that ide_task_t and ata_request_t and struct request usage belong together. This could alleviate the ugly usage of the rq->special field if rq is struct request - which would be a GoodThin(TM).

drivers/ide/ide-disk.c line 120

Quoted 2 lines
drivers/ide/ide-disk.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-disk.c +2 -0
+	args->ar = ar;
+	rq->special = ar;

Same hint as above.

drivers/ide/ide-disk.c line 223

Quoted 10 lines
drivers/ide/ide-disk.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-disk.c +4 -4
 n ata_taskfile(drive,
-			&args.taskfile,
-			&args.hobfile,
-			args.handler,
-			args.prehandler,
+			&args->taskfile,
+			&args->hobfile,
+			args->handler,
+			args->prehandler,
 			rq);

Due to the other cleanups which happened already it was now possible for me to collapse the arguments of the ata_taskfile function to use only one parameter - names ide_task_t. This will immediately allow to consolidate all data specific to a command into one queued structure, which will be named struct ata_request then. I will post the corresponding patch just immediately, since the integration of the tcq stuff will be quite involved with it.

drivers/ide/ide-disk.c line 128

Quoted 2 lines
drivers/ide/ide-disk.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-disk.c +2 -0
+	ide_task_t			*args = &ar->ar_task;
+	struct request			*rq = ar->ar_rq;

See agin they belong together.

drivers/ide/ide-disk.c line 231

Quoted 5 lines
drivers/ide/ide-disk.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-disk.c +4 -0
+	args->ar = ar;
+	rq->special = ar;
 
+	ide_task_t			*args = &ar->ar_task;
+	struct request			*rq = ar->ar_rq;

and again.

drivers/ide/ide-disk.c line 135

Quoted 2 lines
drivers/ide/ide-disk.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-disk.c +2 -0
+	args->ar = ar;
+	rq->special = ar;

and again they belong together and strcut request should not be passed as parameter in IDE code.

drivers/ide/ide-disk.c line 417

Quoted 11 lines
drivers/ide/ide-disk.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-disk.c +3 -3
-		return lba48_do_request(drive, rq, block);
+		return lba48_do_request(drive, ar, block);
 
 	/* 28-bit LBA */
 	if (drive->select.b.lba)
-		return lba28_do_request(drive, rq, block);
+		return lba28_do_request(drive, ar, block);
 
 	/* 28-bit CHS */
-	return chs_do_request(drive, rq, block);
+	return chs_do_request(drive, ar, block);

Didn't I tell we shouldn't be tossing request structs around? :-).

drivers/ide/ide-disk.c line 146

Quoted 3 lines
drivers/ide/ide-disk.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-disk.c +3 -0
+/*
+ * FIXME: taskfiles should be a map of pages, not a long virt address... /jens
+ */

I fully agree with you - possible it will be helpfull to just pee at the SCSI code to see how it should be done...

drivers/ide/ide-disk.c line 150

Quoted 4 lines
drivers/ide/ide-disk.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-disk.c +4 -0
+	if (rq->flags & REQ_DRIVE_TASKFILE)
+		ar->ar_sg_nents = ide_raw_build_sglist(hwif, rq);
+	else 
+		ar->ar_sg_nents = ide_build_sglist(hwif, rq);

Most certainly the switch should be pushed down to one sinde build_sglist function - we are passing the rq anyway to it.

drivers/ide/ide-disk.c line 381

Quoted 7 lines
drivers/ide/ide-disk.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-disk.c +1 -2
@@ -372,10 +378,9 @@
 void ide_destroy_dmatable (ide_drive_t *drive)
 {
 	struct pci_dev *dev = drive->channel->pci_dev;
-	struct scatterlist *sg = drive->channel->sg_table;
-	int nents = drive->channel->sg_nents;
+	ata_request_t *ar = IDE_CUR_AR(drive);

This looks a bit ugly and should be analogous to ata_ar_get() possible ata_ar_current() will fit.

Quoted 9 lines
drivers/ide/ide-disk.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-disk.c +9 -0
+int ide_start_dma(struct ata_channel *hwif, ide_drive_t *drive, ide_dma_action_t func)
+{
+	unsigned int reading = 0, count;
+	unsigned long dma_base = hwif->dma_base;
+	ata_request_t *ar = IDE_CUR_AR(drive);
+
+	if (rq_data_dir(ar->ar_rq) == READ)
+		reading = 1 << 3;
+

drivers/ide/ide-disk.c

Quoted 10 lines
drivers/ide/ide-disk.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-disk.c +10 -0
+	if (hwif->rwproc)
+		hwif->rwproc(drive, func);
+
+	if (!(count = ide_build_dmatable(drive, ar->ar_rq, func)))
+		return 1;	/* try PIO instead of DMA */
+
+	ar->ar_flags |= ATA_AR_SETUP;
+	outl(ar->ar_dmatable, dma_base + 4);	/* PRD table */
+	outb(reading, dma_base);		/* specify r/w */
+	outb(inb(dma_base + 2) | 6, dma_base+2);/* clear INTR & ERROR flags */

Hmmm there is one architecture which will have possbile problems with this namely cris. But right now I'm quite convinced that they should fix something there and the OUT_ IDE code specific compatibility macros should be removed altogether.

Quoted 4 lines

diff -urN -X /home/axboe/cdrom/exclude /opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-features.c linux/drivers/ide/ide-features.c

drivers/ide/ide-features.c line 81

Quoted 10 lines
drivers/ide/ide-features.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-features.c +0 -3
@@ -75,10 +75,7 @@
 char *ide_dmafunc_verbose (ide_dma_action_t dmafunc)
 {
 	switch (dmafunc) {
-		case ide_dma_read:		return("ide_dma_read");
-		case ide_dma_write:		return("ide_dma_write");
 		case ide_dma_begin:		return("ide_dma_begin");
-		case ide_dma_end:		return("ide_dma_end:");
 		case ide_dma_check:		return("ide_dma_check");
 		case ide_dma_on:		return("ide_dma_on");
 		case ide_dma_off:		return("ide_dma_off");

This abortion will be killed by using __FUNCTION__ where apriopriate in debugging code.

drivers/ide/ide-features.c

Quoted 2 lines
drivers/ide/ide-features.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-features.c +2 -0
+	ata_request_t *ar = rq->special;
+	ide_task_t *args = &ar->ar_task;

Did I mention they belong to a single entity :-).

drivers/ide/ide-features.c

Quoted 3 lines
drivers/ide/ide-features.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-features.c +2 -1
-	ide_task_t *args	= HWGROUP(drive)->rq->special;
+	ata_request_t *ar	= HWGROUP(drive)->rq->special;
+	ide_task_t *args	= &ar->ar_task;

Same comment here.

drivers/ide/ide-features.c

Quoted 2 lines
drivers/ide/ide-features.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-features.c +2 -0
+	ata_request_t *ar = rq->special;
+	ide_task_t *args = &ar->ar_task;

And here.

OK I will just "eat" your code this evening...

author
#2 lore raw
In reply to Jens Axboe
Quoted 4 lines · Martin Dalecki
Quoted 4 lines

echo "using_tcq:0" > /proc/ide/hdX/setting

will disable TCQ and revert to DMA,

Quoted 8 lines
Quoted 5 lines

echo "using_tcq:32" > /proc/ide/hdX/setting

will set queue depth to 32, any value in between the two are of course also allowed. The driver will print enable/disable info to the kernel log.

Well this belongs to an ioctl or sysctl... However most of the /proc/ide stuff if not all will go to the sysctl quite soon.

Put it wherever you want it, I'm just making it easier for myself not having to pass patches to hdparm around as well for people to enable taggged queueing.

Quoted 10 lines

drivers/ide/ide-disk.c line 113

Quoted 7 lines

#include <linux/config.h>
#include <linux/module.h>

drivers/ide/ide-disk.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-disk.c +1 -0
@@ -109,53 +110,64 @@
 static u8 get_command(ide_drive_t *drive, int cmd)
 {
 	int lba48bit = (drive->id->cfs_enable_2 & 0x0400) ? 1 : 0;
+	int command = WIN_NOP;

The "incremental" usage of the command variable I think is an overoptimization.

Quite possibly, I couldn't resist since the commands are defined the way there are.

Quoted 8 lines

u8 is the proper type for it anyway. I have unwound the code below once to make it more obvious and you would be surprised what GCC does with it :-).

drivers/ide/ide-disk.c line 162

Quoted 3 lines
drivers/ide/ide-disk.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-disk.c +2 -0
+
+	return command;
 }

See you are returning an int entity as u8!

Oh yeah, woops. Value is ok.

Quoted 6 lines

Review line 118

Quoted 2 lines
(quoted diff) +2 -0
+	ide_task_t			*args = &ar->ar_task;
+	struct request			*rq = ar->ar_rq;

Hints that ide_task_t and ata_request_t and struct request usage belong together. This could alleviate the ugly usage of the rq->special field if rq is struct request - which would be a GoodThin(TM).

Of course, that's my whole point with this ata_request stuff. It's just messy now because I only cared for tcq usage, not cleaning the rest of the cruft.

Quoted 11 lines

drivers/ide/ide-disk.c line 223

Quoted 10 lines
drivers/ide/ide-disk.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-disk.c +4 -4
 n ata_taskfile(drive,
-			&args.taskfile,
-			&args.hobfile,
-			args.handler,
-			args.prehandler,
+			&args->taskfile,
+			&args->hobfile,
+			args->handler,
+			args->prehandler,
 			rq);
Quoted 7 lines

Due to the other cleanups which happened already it was now possible for me to collapse the arguments of the ata_taskfile function to use only one parameter - names ide_task_t. This will immediately allow to consolidate all data specific to a command into one queued structure, which will be named struct ata_request then. I will post the corresponding patch just immediately, since the integration of the tcq stuff will be quite involved with it.

Good, ata_taskfile/ide_wait_taskfile is a horrible interface right now. But you now that :-)

Quoted 7 lines
Quoted 4 lines
(quoted diff) +2 -0
+/*
+ * FIXME: taskfiles should be a map of pages, not a long virt address... 

/jens
+ */

I fully agree with you - possible it will be helpfull to just pee at the SCSI code to see how it should be done...

Just build a big bio, for instance. And hey, look then taskfile and request paths are identical all of a sudden.

Quoted 7 lines

drivers/ide/ide-dma.c line 307

Quoted 4 lines
drivers/ide/ide-dma.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-dma.c +4 -0
+	if (rq->flags & REQ_DRIVE_TASKFILE)
+		ar->ar_sg_nents = ide_raw_build_sglist(hwif, rq);
+	else 
+		ar->ar_sg_nents = ide_build_sglist(hwif, rq);

Most certainly the switch should be pushed down to one sinde build_sglist function - we are passing the rq anyway to it.

See above, they can be unified instead.

Quoted 10 lines

drivers/ide/ide-dma.c line 381

Quoted 7 lines
drivers/ide/ide-dma.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-dma.c +1 -2
@@ -372,10 +378,9 @@
 void ide_destroy_dmatable (ide_drive_t *drive)
 {
 	struct pci_dev *dev = drive->channel->pci_dev;
-	struct scatterlist *sg = drive->channel->sg_table;
-	int nents = drive->channel->sg_nents;
+	ata_request_t *ar = IDE_CUR_AR(drive);

This looks a bit ugly and should be analogous to ata_ar_get() possible ata_ar_current() will fit.

Ok with me, no strong style oppinions here.

Quoted 19 lines
Quoted 19 lines
drivers/ide/ide-dma.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-dma.c +18 -0
+int ide_start_dma(struct ata_channel *hwif, ide_drive_t *drive, 
 ide_dma_action_t func)
+{
+	unsigned int reading = 0, count;
+	unsigned long dma_base = hwif->dma_base;
+	ata_request_t *ar = IDE_CUR_AR(drive);
+
+	if (rq_data_dir(ar->ar_rq) == READ)
+		reading = 1 << 3;
+
+	if (hwif->rwproc)
+		hwif->rwproc(drive, func);
+
+	if (!(count = ide_build_dmatable(drive, ar->ar_rq, func)))
+		return 1;	/* try PIO instead of DMA */
+
+	ar->ar_flags |= ATA_AR_SETUP;
+	outl(ar->ar_dmatable, dma_base + 4);	/* PRD table */
+	outb(reading, dma_base);		/* specify r/w */
Quoted 8 lines
Quoted 2 lines
(quoted diff) +1 -0
+	outb(inb(dma_base + 2) | 6, dma_base+2);/* clear INTR & ERROR flags 

*/

Hmmm there is one architecture which will have possbile problems with this namely cris. But right now I'm quite convinced that they should fix something
there and the OUT_ IDE code specific compatibility macros should be removed altogether.

How is cris working now, then?

Quoted 11 lines
Quoted 11 lines

diff -urN -X /home/axboe/cdrom/exclude /opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-features.c linux/drivers/ide/ide-features.c
--- /opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-features.c Tue Apr 9
11:41:13 2002
+++ linux/drivers/ide/ide-features.c Thu Apr 4 08:14:18 2002

drivers/ide/ide-features.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-features.c +0 -1
@@ -75,10 +75,7 @@
 char *ide_dmafunc_verbose (ide_dma_action_t dmafunc)
 {
 	switch (dmafunc) {
-		case ide_dma_read:		return("ide_dma_read");
Quoted 8 lines

drivers/ide/ide-features.c line 81

Quoted 6 lines
drivers/ide/ide-features.c renamed from opt/kernel/linux-2.5.8-pre2/drivers/ide/ide-features.c +0 -2
-		case ide_dma_write:		return("ide_dma_write");
 		case ide_dma_begin:		return("ide_dma_begin");
-		case ide_dma_end:		return("ide_dma_end:");
 		case ide_dma_check:		return("ide_dma_check");
 		case ide_dma_on:		return("ide_dma_on");
 		case ide_dma_off:		return("ide_dma_off");

This abortion will be killed by using __FUNCTION__ where apriopriate in debugging code.

Good!

Quoted 1 line

OK I will just "eat" your code this evening...

Looking forward to the merge work ahead :-)

Signature · 1 line
Jens Axboe
#3 lore raw
In reply to Jens Axboe
Quoted 3 lines · Jens Axboe

Hi,

Version 2 is ready. Changes since last time:

Hi,

OK I have managed to merge this with the 2.5.8-pre2 + ide-29b at home. However since we have now apparently already a -pre3 I will have to at least redo the patches against it. If this takes more then the time needed for a cup of coffe I will have unfortuntely to do it today afternoon.

author
#4 lore raw
In reply to Jens Axboe
Quoted 11 lines · Martin Dalecki
Quoted 3 lines · Jens Axboe

Hi,

Version 2 is ready. Changes since last time:

Hi,

OK I have managed to merge this with the 2.5.8-pre2 + ide-29b at home. However since we have now apparently already a -pre3 I will have to at least redo the patches against it. If this takes more then the time needed for a cup of coffe I will have unfortuntely to do it today afternoon.

I'm already running 2.5.8-pre3 (which appears to include ide-29b, right?) + ide-tcq here, so you should probably not waste any effort on that :-)

I'll post an updated patch later today.

Signature · 1 line
Jens Axboe
#5 lore raw
In reply to Jens Axboe
Quoted 17 lines · Jens Axboe
Quoted 6 lines · Martin Dalecki
Quoted 3 lines · Jens Axboe

Hi,

Version 2 is ready. Changes since last time:

Quoted 7 lines

Hi,

OK I have managed to merge this with the 2.5.8-pre2 + ide-29b at home. However since we have now apparently already a -pre3 I will have to at least redo the patches against it. If this takes more then the time needed for a cup of coffe I will have unfortuntely to do it today afternoon.

Quoted 3 lines

I'm already running 2.5.8-pre3 (which appears to include ide-29b, right?) + ide-tcq here, so you should probably not waste any effort on that :-)

Well than I will have to basically redo all the stuff I did in between... like for example nuking the number of parameters to ata_taskfile()... :-(.

Quoted 1 line

I'll post an updated patch later today.

Fine.

author
#6 lore raw
In reply to Jens Axboe
Quoted 18 lines · Martin Dalecki
Quoted 17 lines · Jens Axboe
Quoted 13 lines · Martin Dalecki
Quoted 3 lines · Jens Axboe

Hi,

Version 2 is ready. Changes since last time:

Hi,

OK I have managed to merge this with the 2.5.8-pre2 + ide-29b at home. However since we have now apparently already a -pre3 I will have to at least redo the patches against it. If this takes more then the time needed for a cup of coffe I will have unfortuntely to do it today afternoon.

Quoted 7 lines
Quoted 3 lines

I'm already running 2.5.8-pre3 (which appears to include ide-29b, right?) + ide-tcq here, so you should probably not waste any effort on that :-)

Well than I will have to basically redo all the stuff I did in between... like for example nuking the number of parameters to ata_taskfile()... :-(.

Ok, go ahead with the merge then and keep your changes. I'll just diff #2 -> current and apply that to whatever shows up in the next kernel.

Signature · 1 line
Jens Axboe
#7 lore raw
In reply to Jens Axboe
Quoted 11 lines · Jens Axboe
Quoted 7 lines
Quoted 3 lines

I'm already running 2.5.8-pre3 (which appears to include ide-29b, right?) + ide-tcq here, so you should probably not waste any effort on that :-)

Well than I will have to basically redo all the stuff I did in between... like for example nuking the number of parameters to ata_taskfile()... :-(.

Ok, go ahead with the merge then and keep your changes. I'll just diff #2 -> current and apply that to whatever shows up in the next kernel.

At least I can tell you now that ide_wait_taskfile as well ide_raw_taskfile are not far from beeing only history right now :-).