public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH] only use 48-bit lba when necessary
@ 2003-04-18  1:34 Chuck Ebbert
  2003-04-18  4:18 ` Matt Mackall
  2003-04-18 14:34 ` Timothy Miller
  0 siblings, 2 replies; 18+ messages in thread
From: Chuck Ebbert @ 2003-04-18  1:34 UTC (permalink / raw)
  To: Matt Mackall; +Cc: linux-kernel

Matt Mackall wrote:


>FYI, GCC as of 3.2.3 doesn't yet reduce the if(...) form to branchless
>code but the & and && versions come out the same with -O2.


  The operands of & can be evaluated in any order, while && requires
left-to-right and does not evaluate the right operand if the left one
is false.  Only the simplest cases could possibly generate the same
code.

--
 Chuck

^ permalink raw reply	[flat|nested] 18+ messages in thread
* Re: [PATCH] only use 48-bit lba when necessary
@ 2003-04-18  9:50 Chuck Ebbert
  0 siblings, 0 replies; 18+ messages in thread
From: Chuck Ebbert @ 2003-04-18  9:50 UTC (permalink / raw)
  To: linux-kernel@horizon.com; +Cc: linux-kernel


>>   The operands of & can be evaluated in any order, while && requires
>> left-to-right and does not evaluate the right operand if the left one
>> is false.  Only the simplest cases could possibly generate the same
>> code.
>
> The code must execute AS IF the right operand is only evaluated if the left
> operand is true.
>
> If an optimizer can prove that evaluating an operand has no side effects
> (which a halfway-decent optimizer can usually do for simple expressions),
> then it is free to evaluate it in any way that will produce the same
> result.


  No, that's not quite right.  Take this code for example:

   struct foo *bar;

   if (bar && bar->baz == 6) /* something */;

If bar were zero, then evaluating the right side of the && would cause
a fault.  (This is not a side effect.)

  So the AS IF part if your statement is right but you have to consider
more than just side effects.

 --
 Chuck

^ permalink raw reply	[flat|nested] 18+ messages in thread
* Re: [PATCH] only use 48-bit lba when necessary
@ 2003-04-18  3:32 linux-kernel
  0 siblings, 0 replies; 18+ messages in thread
From: linux-kernel @ 2003-04-18  3:32 UTC (permalink / raw)
  To: 76306.1226; +Cc: linux-kernel

Matt Mackall wrote:
>> FYI, GCC as of 3.2.3 doesn't yet reduce the if(...) form to branchless
>> code but the & and && versions come out the same with -O2.

And Chuck Ebbert replied:
>   The operands of & can be evaluated in any order, while && requires
> left-to-right and does not evaluate the right operand if the left one
> is false.  Only the simplest cases could possibly generate the same
> code.

The code must execute AS IF the right operand is only evaluated if the left
operand is true.

If an optimizer can prove that evaluating an operand has no side effects
(which a halfway-decent optimizer can usually do for simple expressions),
then it is free to evaluate it in any way that will produce the same
result.

For example, if both operands of && have no side effects, then the compiler
is free to convert

if ( expensive() && cheap() ) {...}

into

if ( cheap() && expensive() ) {...}

although I expect most assume the programmer was sensible enough to
put the most commonly failed tests first.


The compiler is also free to do the same to

if ( !!cheap() & !!expensive() ) {...}

Again, it has to behave AS IF !!expensive() were evaluated in every
case, but if it can prove that there are no side effects, it can
skip expensive() entirely if there appears to be reason to do so.


The upshot of this is that, if the conditions have no side effects and
the compiler is decent, there should be NO DIFFERENCE in the compiled code.

Since it is only legal to convert between && and & if the right operand
has no side effects and does not depend on any side effects of the left
operand, the only time it makes sense to choose one over the other for
any reason but coding style is if A) the code is speed-critical, and B)
you know the conditions are met but you don't think the optimizer can
figure it out.

Which is pretty uncommon.


Regarding style, personally I'm used to C's zero/non-zero boolean tests
and prefer to write "while (p)" and "if (x & MASK)".  Using bare &
between such expressions is more difficult to read for two reasons:
A) the reader has to parse the "!!(...) " or "... != 0" clutter around
   each operand, and
B) the reader has to figure out that the "1 & 2" case never happens.

With |. that can often be avoided, but not with pointer operands.

^ permalink raw reply	[flat|nested] 18+ messages in thread
* Re: [PATCH] only use 48-bit lba when necessary
@ 2003-04-04 17:02 Chuck Ebbert
  2003-04-17 14:20 ` Matt Mackall
  0 siblings, 1 reply; 18+ messages in thread
From: Chuck Ebbert @ 2003-04-04 17:02 UTC (permalink / raw)
  To: linux-kernel

Juan Quintela wrote:


>Reason is that:
>
>if (expr)
>   var = true;
>else
>   var = false;
>
>is always a bad construct.
>
>var = expr;
>
>is a better construct to express that meaning.


 Yes, but:

   if (expr1 && expr2)
      var = true;
   else
      var = false;

is usually better turned into something that avoids jumps
when it's safe to evaluate both parts unconditionally:

   var = (expr1 != 0) & (expr2 != 0);

or (if you can stand it):

   var = !!expr1 & !!expr2;


--
 Chuck

^ permalink raw reply	[flat|nested] 18+ messages in thread
* [PATCH] only use 48-bit lba when necessary
@ 2003-04-04 12:29 Jens Axboe
  2003-04-04 13:19 ` Juan Quintela
  2003-04-04 14:40 ` Andries Brouwer
  0 siblings, 2 replies; 18+ messages in thread
From: Jens Axboe @ 2003-04-04 12:29 UTC (permalink / raw)
  To: Linux Kernel, Alan Cox

Hi,

48-bit lba has a non-significant overhead (twice the outb's, 12 instead
of 6 per command), so it makes sense to use 28-bit lba commands whenever
we can.

Patch is against 2.5.66-BK.

===== drivers/ide/ide-disk.c 1.36 vs edited =====
--- 1.36/drivers/ide/ide-disk.c	Wed Mar 26 21:23:01 2003
+++ edited/drivers/ide/ide-disk.c	Fri Apr  4 14:18:41 2003
@@ -367,12 +367,15 @@
 static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
-	u8 lba48		= (drive->addressing == 1) ? 1 : 0;
+	u8 lba48		= 0;
 	task_ioreg_t command	= WIN_NOP;
 	ata_nsector_t		nsectors;
 
 	nsectors.all		= (u16) rq->nr_sectors;
 
+	if (drive->addressing == 1 && block > 0xfffffff)
+		lba48 = 1;
+
 	if (driver_blocked)
 		panic("Request while ide driver is blocked?");
 
@@ -392,7 +395,7 @@
 		hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
 
 	if (drive->select.b.lba) {
-		if (drive->addressing == 1) {
+		if (lba48) {
 			task_ioreg_t tasklets[10];
 
 			if (blk_rq_tagged(rq)) {
@@ -502,6 +505,7 @@
 		command = ((drive->mult_count) ?
 			   ((lba48) ? WIN_MULTREAD_EXT : WIN_MULTREAD) :
 			   ((lba48) ? WIN_READ_EXT : WIN_READ));
+
 		ide_execute_command(drive, command, &read_intr, WAIT_CMD, NULL);
 		return ide_started;
 	} else if (rq_data_dir(rq) == WRITE) {
@@ -577,6 +581,11 @@
  */
 static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block)
 {
+	int lba48bit = 0;
+
+	if (drive->addressing == 1 && block > 0xfffffff)
+		lba48bit = 1;
+
 	BUG_ON(drive->blocked);
 	if (!blk_fs_request(rq)) {
 		blk_dump_rq_flags(rq, "do_rw_disk - bad command");
@@ -602,7 +611,7 @@
 		return ide_started;
 	}
 
-	if (drive->addressing == 1)		/* 48-bit LBA */
+	if (lba48bit && block > 0xfffffff)
 		return lba_48_rw_disk(drive, rq, (unsigned long long) block);
 	if (drive->select.b.lba)		/* 28-bit LBA */
 		return lba_28_rw_disk(drive, rq, (unsigned long) block);
@@ -611,9 +620,13 @@
 	return chs_rw_disk(drive, rq, (unsigned long) block);
 }
 
-static task_ioreg_t get_command (ide_drive_t *drive, int cmd)
+static task_ioreg_t get_command (ide_drive_t *drive, struct request *rq)
 {
-	int lba48bit = (drive->addressing == 1) ? 1 : 0;
+	int cmd = rq_data_dir(rq);
+	int lba48bit = 0;
+
+	if (drive->addressing == 1 && rq->sector > 0xfffffff)
+		lba48bit = 1;
 
 	if ((cmd == READ) && drive->using_tcq)
 		return lba48bit ? WIN_READDMA_QUEUED_EXT : WIN_READDMA_QUEUED;
@@ -640,7 +653,7 @@
 	ide_task_t		args;
 	int			sectors;
 	ata_nsector_t		nsectors;
-	task_ioreg_t command	= get_command(drive, rq_data_dir(rq));
+	task_ioreg_t command	= get_command(drive, rq);
 	unsigned int track	= (block / drive->sect);
 	unsigned int sect	= (block % drive->sect) + 1;
 	unsigned int head	= (track % drive->head);
@@ -672,6 +685,7 @@
 	args.tfRegister[IDE_SELECT_OFFSET]	|= drive->select.all;
 	args.tfRegister[IDE_COMMAND_OFFSET]	= command;
 	args.command_type			= ide_cmd_type_parser(&args);
+	args.addressing				= 0;
 	args.rq					= (struct request *) rq;
 	rq->special				= (ide_task_t *)&args;
 	return do_rw_taskfile(drive, &args);
@@ -682,7 +696,7 @@
 	ide_task_t		args;
 	int			sectors;
 	ata_nsector_t		nsectors;
-	task_ioreg_t command	= get_command(drive, rq_data_dir(rq));
+	task_ioreg_t command	= get_command(drive, rq);
 
 	nsectors.all = (u16) rq->nr_sectors;
 
@@ -710,6 +724,7 @@
 	args.tfRegister[IDE_SELECT_OFFSET]	|= drive->select.all;
 	args.tfRegister[IDE_COMMAND_OFFSET]	= command;
 	args.command_type			= ide_cmd_type_parser(&args);
+	args.addressing				= 0;
 	args.rq					= (struct request *) rq;
 	rq->special				= (ide_task_t *)&args;
 	return do_rw_taskfile(drive, &args);
@@ -726,7 +741,7 @@
 	ide_task_t		args;
 	int			sectors;
 	ata_nsector_t		nsectors;
-	task_ioreg_t command	= get_command(drive, rq_data_dir(rq));
+	task_ioreg_t command	= get_command(drive, rq);
 
 	nsectors.all = (u16) rq->nr_sectors;
 
@@ -762,6 +777,7 @@
 	args.hobRegister[IDE_SELECT_OFFSET_HOB]	= drive->select.all;
 	args.hobRegister[IDE_CONTROL_OFFSET_HOB]= (drive->ctl|0x80);
 	args.command_type			= ide_cmd_type_parser(&args);
+	args.addressing				= 1;
 	args.rq					= (struct request *) rq;
 	rq->special				= (ide_task_t *)&args;
 	return do_rw_taskfile(drive, &args);
===== drivers/ide/ide-dma.c 1.13 vs edited =====
--- 1.13/drivers/ide/ide-dma.c	Fri Mar  7 18:14:31 2003
+++ edited/drivers/ide/ide-dma.c	Fri Apr  4 14:15:37 2003
@@ -653,7 +653,7 @@
 	ide_hwif_t *hwif	= HWIF(drive);
 	struct request *rq	= HWGROUP(drive)->rq;
 	unsigned int reading	= 1 << 3;
-	u8 lba48		= (drive->addressing == 1) ? 1 : 0;
+	u8 lba48		= 0;
 	task_ioreg_t command	= WIN_NOP;
 
 	/* try pio */
@@ -663,11 +663,14 @@
 	if (drive->media != ide_disk)
 		return 0;
 
+	if (drive->addressing == 1 && rq->sector > 0xfffffff)
+		lba48 = 1;
+
 	command = (lba48) ? WIN_READDMA_EXT : WIN_READDMA;
-	
+
 	if (drive->vdma)
 		command = (lba48) ? WIN_READ_EXT: WIN_READ;
-		
+
 	if (rq->flags & REQ_DRIVE_TASKFILE) {
 		ide_task_t *args = rq->special;
 		command = args->tfRegister[IDE_COMMAND_OFFSET];
@@ -685,7 +688,7 @@
 	ide_hwif_t *hwif	= HWIF(drive);
 	struct request *rq	= HWGROUP(drive)->rq;
 	unsigned int reading	= 0;
-	u8 lba48		= (drive->addressing == 1) ? 1 : 0;
+	u8 lba48		= 0;
 	task_ioreg_t command	= WIN_NOP;
 
 	/* try PIO instead of DMA */
@@ -695,10 +698,13 @@
 	if (drive->media != ide_disk)
 		return 0;
 
+	if (drive->addressing == 1 && rq->sector > 0xfffffff)
+		lba48 = 1;
+
 	command = (lba48) ? WIN_WRITEDMA_EXT : WIN_WRITEDMA;
 	if (drive->vdma)
 		command = (lba48) ? WIN_WRITE_EXT: WIN_WRITE;
-		
+
 	if (rq->flags & REQ_DRIVE_TASKFILE) {
 		ide_task_t *args = rq->special;
 		command = args->tfRegister[IDE_COMMAND_OFFSET];
===== drivers/ide/ide-taskfile.c 1.14 vs edited =====
--- 1.14/drivers/ide/ide-taskfile.c	Wed Mar 26 21:22:22 2003
+++ edited/drivers/ide/ide-taskfile.c	Fri Apr  4 14:20:26 2003
@@ -147,7 +147,7 @@
 	ide_hwif_t *hwif	= HWIF(drive);
 	task_struct_t *taskfile	= (task_struct_t *) task->tfRegister;
 	hob_struct_t *hobfile	= (hob_struct_t *) task->hobRegister;
-	u8 HIHI			= (drive->addressing == 1) ? 0xE0 : 0xEF;
+	u8 HIHI			= task->addressing == 1 ? 0xE0 : 0xEF;
 
 #ifdef CONFIG_IDE_TASK_IOCTL_DEBUG
 	void debug_taskfile(drive, task);
@@ -160,7 +160,7 @@
 	}
 	SELECT_MASK(drive, 0);
 
-	if (drive->addressing == 1) {
+	if (task->addressing == 1) {
 		hwif->OUTB(hobfile->feature, IDE_FEATURE_REG);
 		hwif->OUTB(hobfile->sector_count, IDE_NSECTOR_REG);
 		hwif->OUTB(hobfile->sector_number, IDE_SECTOR_REG);
@@ -332,7 +332,7 @@
 	args->tfRegister[IDE_STATUS_OFFSET]  = stat;
 	if ((drive->id->command_set_2 & 0x0400) &&
 	    (drive->id->cfs_enable_2 & 0x0400) &&
-	    (drive->addressing == 1)) {
+	    (args->addressing == 1)) {
 		hwif->OUTB(drive->ctl|0x80, IDE_CONTROL_REG_HOB);
 		args->hobRegister[IDE_FEATURE_OFFSET_HOB] = hwif->INB(IDE_FEATURE_REG);
 		args->hobRegister[IDE_NSECTOR_OFFSET_HOB] = hwif->INB(IDE_NSECTOR_REG);
@@ -1795,13 +1795,13 @@
 	 */
 	if (task->tf_out_flags.all == 0) {
 		task->tf_out_flags.all = IDE_TASKFILE_STD_OUT_FLAGS;
-		if (drive->addressing == 1)
+		if (task->addressing == 1)
 			task->tf_out_flags.all |= (IDE_HOB_STD_OUT_FLAGS << 8);
         }
 
 	if (task->tf_in_flags.all == 0) {
 		task->tf_in_flags.all = IDE_TASKFILE_STD_IN_FLAGS;
-		if (drive->addressing == 1)
+		if (task->addressing == 1)
 			task->tf_in_flags.all |= (IDE_HOB_STD_IN_FLAGS  << 8);
         }
 
===== include/linux/ide.h 1.42 vs edited =====
--- 1.42/include/linux/ide.h	Thu Mar 20 19:23:19 2003
+++ edited/include/linux/ide.h	Fri Apr  4 14:07:50 2003
@@ -1408,6 +1408,7 @@
 	ide_reg_valid_t		tf_in_flags;
 	int			data_phase;
 	int			command_type;
+	int			addressing;	/* 1 for 48-bit */
 	ide_pre_handler_t	*prehandler;
 	ide_handler_t		*handler;
 	ide_post_handler_t	*posthandler;

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2003-04-18 14:07 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-04-18  1:34 [PATCH] only use 48-bit lba when necessary Chuck Ebbert
2003-04-18  4:18 ` Matt Mackall
2003-04-18 14:34 ` Timothy Miller
  -- strict thread matches above, loose matches on Subject: below --
2003-04-18  9:50 Chuck Ebbert
2003-04-18  3:32 linux-kernel
2003-04-04 17:02 Chuck Ebbert
2003-04-17 14:20 ` Matt Mackall
2003-04-17 15:24   ` Timothy Miller
2003-04-17 16:05     ` Matt Mackall
2003-04-17 18:49       ` Timothy Miller
2003-04-04 12:29 Jens Axboe
2003-04-04 13:19 ` Juan Quintela
2003-04-04 13:22   ` Jens Axboe
2003-04-04 15:48     ` Juan Quintela
2003-04-04 15:54       ` Jens Axboe
2003-04-04 17:06         ` John Bradford
2003-04-04 14:40 ` Andries Brouwer
2003-04-04 15:13   ` Jens Axboe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox