linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* RE: [UPDATED][PATCH 2.6.14]: ide: Enable larger taskfile transfers
@ 2005-11-01 20:24 Timothy Thelin
  2005-11-02  8:49 ` Jens Axboe
  0 siblings, 1 reply; 9+ messages in thread
From: Timothy Thelin @ 2005-11-01 20:24 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Bartlomiej Zolnierkiewicz, linux-ide


> On Tue, Nov 01 2005, Timothy Thelin wrote:
> > Changes:
> > Increases the taskfile data transfer limit from 128K to a
> > theoretical 2-4MB (arch dependant) by using __get_free_pages
> > instead of kmalloc.  Note that larger requests have a lower
> > success rate because of needing to find a larger amount of
> > free consecutive memory.
> 
> I don't think this is a good way to do it. IDE already supports sg for
> regular fs requests, the correct solution would be to make 
> sure the user
> driven taskfile submission is sg based as well. That would 
> enable large
> transfers without risking allocation failures.

Agreed. I looked into doing sg first, but the changes
required would be more invasive and have a higher risk of
breaking existing things. This was targeted as an interim
solution by someone without lots of ide core experience
until someone came up with a proper sg solution.

> An interface that doesn't
> work for anything but a freshly booted kernel is pretty 
> worthless, imho.
> User interfaces must work predictably.
> 

A question though: is __get_free_pages less successful than
kmalloc in returning the same sized chunk of memory?  If
it's the same success rate (and I thought it was, is it not?),
then up to 128K the interface acts just like before, but now it
can possibly do larger transfers rather than having no
ability to do larger transfers.

My personal interests are in transfering data in the
130K-140K range, just over what kmalloc can do, and 
this interim solution has been great for that.

It might be possible for me to begin work on an sg solution
in a couple of weeks (design advice anyone?).


Regards,
Tim Thelin

^ permalink raw reply	[flat|nested] 9+ messages in thread
* RE: [UPDATED][PATCH 2.6.14]: ide: Enable larger taskfile transfers
@ 2005-11-02 20:42 Timothy Thelin
  0 siblings, 0 replies; 9+ messages in thread
From: Timothy Thelin @ 2005-11-02 20:42 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz, Martin Murray; +Cc: Jens Axboe, linux-ide


Hi,

> 
>  <snip>
> >
> >     One thing I don't understand is, if Mr. Thelin's code 
> that requests,
> > as said, a little over 128k is a DMA command, then 
> shouldn't the kernel
> > have bugged? And if it didn't bug, was the data transferred 
> via PIO? Or
> 
> I suppose so.
> 

Yes, the transfers were all PIO

Regards,
Tim Thelin

^ permalink raw reply	[flat|nested] 9+ messages in thread
* RE: [UPDATED][PATCH 2.6.14]: ide: Enable larger taskfile transfers
@ 2005-11-01 19:17 Timothy Thelin
  0 siblings, 0 replies; 9+ messages in thread
From: Timothy Thelin @ 2005-11-01 19:17 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz, linux-ide


Hi again,

I had a brain malfunction and gave the wrong email
address on the signed-off line, sorry about that.

Here is the correct one:
Signed-off-by: Timothy Thelin <timothy.thelin@wdc.com>

Regards,
Tim Thelin

> -----Original Message-----
> From: linux-ide-owner@vger.kernel.org
> [mailto:linux-ide-owner@vger.kernel.org]On Behalf Of Timothy Thelin
> Sent: Tuesday, November 01, 2005 11:06 AM
> To: Bartlomiej Zolnierkiewicz; linux-ide@vger.kernel.org
> Subject: [UPDATED][PATCH 2.6.14]: ide: Enable larger taskfile 
> transfers
> 
> 
> Hi all,
> 
> Here is for review the cleaned up version of the patch
> that allows ide taskfile transfers to be larger than 128K.
> 
> I've validated on my x86 that its possible to do 4MB
> read sectors extended and write sectors extended, smaller
> transfers with smart read log and smart write log, and
> some non-data commands.
> 
> It's attached as well, since what's below is going to get
> line wrapped.
> 
> Thanks,
> Tim Thelin
> 
> Changes:
> Increases the taskfile data transfer limit from 128K to a
> theoretical 2-4MB (arch dependant) by using __get_free_pages
> instead of kmalloc.  Note that larger requests have a lower
> success rate because of needing to find a larger amount of
> free consecutive memory.
> 
> Signed-off-by: Timothy Thelin <tthelin@wdc.com>
> 
> ============
> 
> diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
> --- a/drivers/ide/ide-taskfile.c
> +++ b/drivers/ide/ide-taskfile.c
> @@ -511,6 +511,27 @@ int ide_raw_taskfile (ide_drive_t *drive
>  
>  EXPORT_SYMBOL(ide_raw_taskfile);
>  
> +static int ide_xfrsize_to_pageorder(int size)
> +{
> +	int pageorder, x, num;
> +
> +	num = size / PAGE_SIZE;
> +	if (size % PAGE_SIZE)
> +		++num;
> +
> +	pageorder = 0;
> +	for (x = sizeof(num) * 8 - 1; x >= 0; --x) {
> +		if ((num >> x) & 1) {
> +			if (pageorder) {
> +				++pageorder;
> +				break;
> +			} else
> +				pageorder = x;
> +		}
> +	}
> +	return pageorder;
> +}
> +
>  int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int 
> cmd, unsigned long
> arg)
>  {
>  	ide_task_request_t	*req_task;
> @@ -523,6 +544,8 @@ int ide_taskfile_ioctl (ide_drive_t *dri
>  	int tasksize		= sizeof(struct ide_task_request_s);
>  	int taskin		= 0;
>  	int taskout		= 0;
> +	int inorder		= 0;
> +	int outorder    	= 0;
>  	u8 io_32bit		= drive->io_32bit;
>  	char __user *buf = (char __user *)arg;
>  
> @@ -541,7 +564,8 @@ int ide_taskfile_ioctl (ide_drive_t *dri
>  
>  	if (taskout) {
>  		int outtotal = tasksize;
> -		outbuf = kmalloc(taskout, GFP_KERNEL);
> +		outorder = ide_xfrsize_to_pageorder(taskout);
> +		outbuf = (u8*)__get_free_pages(GFP_KERNEL, outorder);
>  		if (outbuf == NULL) {
>  			err = -ENOMEM;
>  			goto abort;
> @@ -555,7 +579,8 @@ int ide_taskfile_ioctl (ide_drive_t *dri
>  
>  	if (taskin) {
>  		int intotal = tasksize + taskout;
> -		inbuf = kmalloc(taskin, GFP_KERNEL);
> +		inorder = ide_xfrsize_to_pageorder(taskin);
> +		inbuf = (u8*)__get_free_pages(GFP_KERNEL, inorder);
>  		if (inbuf == NULL) {
>  			err = -ENOMEM;
>  			goto abort;
> @@ -650,9 +675,9 @@ int ide_taskfile_ioctl (ide_drive_t *dri
>  abort:
>  	kfree(req_task);
>  	if (outbuf != NULL)
> -		kfree(outbuf);
> +		free_pages((unsigned long)outbuf, outorder);
>  	if (inbuf != NULL)
> -		kfree(inbuf);
> +		free_pages((unsigned long)inbuf, inorder);
>  
>  //	printk("IDE Taskfile ioctl ended. rc = %i\n", err);
>  
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread
* [UPDATED][PATCH 2.6.14]: ide: Enable larger taskfile transfers
@ 2005-11-01 19:06 Timothy Thelin
  2005-11-01 19:27 ` Jens Axboe
  0 siblings, 1 reply; 9+ messages in thread
From: Timothy Thelin @ 2005-11-01 19:06 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz, linux-ide

[-- Attachment #1: Type: text/plain, Size: 2767 bytes --]

Hi all,

Here is for review the cleaned up version of the patch
that allows ide taskfile transfers to be larger than 128K.

I've validated on my x86 that its possible to do 4MB
read sectors extended and write sectors extended, smaller
transfers with smart read log and smart write log, and
some non-data commands.

It's attached as well, since what's below is going to get
line wrapped.

Thanks,
Tim Thelin

Changes:
Increases the taskfile data transfer limit from 128K to a
theoretical 2-4MB (arch dependant) by using __get_free_pages
instead of kmalloc.  Note that larger requests have a lower
success rate because of needing to find a larger amount of
free consecutive memory.

Signed-off-by: Timothy Thelin <tthelin@wdc.com>

============

diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -511,6 +511,27 @@ int ide_raw_taskfile (ide_drive_t *drive
 
 EXPORT_SYMBOL(ide_raw_taskfile);
 
+static int ide_xfrsize_to_pageorder(int size)
+{
+	int pageorder, x, num;
+
+	num = size / PAGE_SIZE;
+	if (size % PAGE_SIZE)
+		++num;
+
+	pageorder = 0;
+	for (x = sizeof(num) * 8 - 1; x >= 0; --x) {
+		if ((num >> x) & 1) {
+			if (pageorder) {
+				++pageorder;
+				break;
+			} else
+				pageorder = x;
+		}
+	}
+	return pageorder;
+}
+
 int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long
arg)
 {
 	ide_task_request_t	*req_task;
@@ -523,6 +544,8 @@ int ide_taskfile_ioctl (ide_drive_t *dri
 	int tasksize		= sizeof(struct ide_task_request_s);
 	int taskin		= 0;
 	int taskout		= 0;
+	int inorder		= 0;
+	int outorder    	= 0;
 	u8 io_32bit		= drive->io_32bit;
 	char __user *buf = (char __user *)arg;
 
@@ -541,7 +564,8 @@ int ide_taskfile_ioctl (ide_drive_t *dri
 
 	if (taskout) {
 		int outtotal = tasksize;
-		outbuf = kmalloc(taskout, GFP_KERNEL);
+		outorder = ide_xfrsize_to_pageorder(taskout);
+		outbuf = (u8*)__get_free_pages(GFP_KERNEL, outorder);
 		if (outbuf == NULL) {
 			err = -ENOMEM;
 			goto abort;
@@ -555,7 +579,8 @@ int ide_taskfile_ioctl (ide_drive_t *dri
 
 	if (taskin) {
 		int intotal = tasksize + taskout;
-		inbuf = kmalloc(taskin, GFP_KERNEL);
+		inorder = ide_xfrsize_to_pageorder(taskin);
+		inbuf = (u8*)__get_free_pages(GFP_KERNEL, inorder);
 		if (inbuf == NULL) {
 			err = -ENOMEM;
 			goto abort;
@@ -650,9 +675,9 @@ int ide_taskfile_ioctl (ide_drive_t *dri
 abort:
 	kfree(req_task);
 	if (outbuf != NULL)
-		kfree(outbuf);
+		free_pages((unsigned long)outbuf, outorder);
 	if (inbuf != NULL)
-		kfree(inbuf);
+		free_pages((unsigned long)inbuf, inorder);
 
 //	printk("IDE Taskfile ioctl ended. rc = %i\n", err);
 

[-- Attachment #2: ide-enable-larger-taskfile-transfers.patch --]
[-- Type: application/octet-stream, Size: 1923 bytes --]

diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -511,6 +511,27 @@ int ide_raw_taskfile (ide_drive_t *drive
 
 EXPORT_SYMBOL(ide_raw_taskfile);
 
+static int ide_xfrsize_to_pageorder(int size)
+{
+	int pageorder, x, num;
+
+	num = size / PAGE_SIZE;
+	if (size % PAGE_SIZE)
+		++num;
+
+	pageorder = 0;
+	for (x = sizeof(num) * 8 - 1; x >= 0; --x) {
+		if ((num >> x) & 1) {
+			if (pageorder) {
+				++pageorder;
+				break;
+			} else
+				pageorder = x;
+		}
+	}
+	return pageorder;
+}
+
 int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
 {
 	ide_task_request_t	*req_task;
@@ -523,6 +544,8 @@ int ide_taskfile_ioctl (ide_drive_t *dri
 	int tasksize		= sizeof(struct ide_task_request_s);
 	int taskin		= 0;
 	int taskout		= 0;
+	int inorder		= 0;
+	int outorder    	= 0;
 	u8 io_32bit		= drive->io_32bit;
 	char __user *buf = (char __user *)arg;
 
@@ -541,7 +564,8 @@ int ide_taskfile_ioctl (ide_drive_t *dri
 
 	if (taskout) {
 		int outtotal = tasksize;
-		outbuf = kmalloc(taskout, GFP_KERNEL);
+		outorder = ide_xfrsize_to_pageorder(taskout);
+		outbuf = (u8*)__get_free_pages(GFP_KERNEL, outorder);
 		if (outbuf == NULL) {
 			err = -ENOMEM;
 			goto abort;
@@ -555,7 +579,8 @@ int ide_taskfile_ioctl (ide_drive_t *dri
 
 	if (taskin) {
 		int intotal = tasksize + taskout;
-		inbuf = kmalloc(taskin, GFP_KERNEL);
+		inorder = ide_xfrsize_to_pageorder(taskin);
+		inbuf = (u8*)__get_free_pages(GFP_KERNEL, inorder);
 		if (inbuf == NULL) {
 			err = -ENOMEM;
 			goto abort;
@@ -650,9 +675,9 @@ int ide_taskfile_ioctl (ide_drive_t *dri
 abort:
 	kfree(req_task);
 	if (outbuf != NULL)
-		kfree(outbuf);
+		free_pages((unsigned long)outbuf, outorder);
 	if (inbuf != NULL)
-		kfree(inbuf);
+		free_pages((unsigned long)inbuf, inorder);
 
 //	printk("IDE Taskfile ioctl ended. rc = %i\n", err);
 

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

end of thread, other threads:[~2005-11-03 21:44 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-11-01 20:24 [UPDATED][PATCH 2.6.14]: ide: Enable larger taskfile transfers Timothy Thelin
2005-11-02  8:49 ` Jens Axboe
2005-11-02 17:23   ` Martin Murray
2005-11-02 19:12     ` Bartlomiej Zolnierkiewicz
2005-11-03 21:43   ` Martin Murray
  -- strict thread matches above, loose matches on Subject: below --
2005-11-02 20:42 Timothy Thelin
2005-11-01 19:17 Timothy Thelin
2005-11-01 19:06 Timothy Thelin
2005-11-01 19:27 ` Jens Axboe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).