Re: [PATCH] usbhid: use GFP_NOIO in reset code path

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Oct 11, 2012 at 12:00 AM, Ming Lei <tom.leiming@xxxxxxxxx> wrote:
>
> Keeping allowed gfp_flag inside task_struct should be one solution, and
> let that teach mm to allocate memory, see the draft idea below:
>
> diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
> index c0543c8..781447f 100644
> --- a/drivers/usb/storage/transport.c
> +++ b/drivers/usb/storage/transport.c
> @@ -1329,11 +1329,13 @@ EXPORT_SYMBOL_GPL(usb_stor_Bulk_reset);
>  int usb_stor_port_reset(struct us_data *us)
>  {
>         int result;
> +       gfp_t orig_gfp = tsk_get_allowd_gfp(current);
>
>         /*for these devices we must use the class specific method */
>         if (us->pusb_dev->quirks & USB_QUIRK_RESET)
>                 return -EPERM;
>
> +       tsk_set_allowd_gfp(current, orig_gfp & ~GFP_IOFS);
>         result = usb_lock_device_for_reset(us->pusb_dev, us->pusb_intf);
>         if (result < 0)
>                 US_DEBUGP("unable to lock device for reset: %d\n", result);
> @@ -1349,5 +1351,6 @@ int usb_stor_port_reset(struct us_data *us)
>                 }
>                 usb_unlock_device(us->pusb_dev);
>         }
> +       tsk_set_allowd_gfp(current, orig_gfp);
>         return result;

In fact, the error handling case may be generalized to the context
which is doing the actual IO transfer, and the change on mass storage
should be as below. We can find other similar situations too, such as
mmc thread(mmc_queue_thread).

I will study the problem further so that more block drivers or
subsystem can benefit from the idea, which may help to persuade
LKML people to accept it.

diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 12aa726..29ad4ac 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -297,7 +297,9 @@ static int usb_stor_control_thread(void * __us)
 {
 	struct us_data *us = (struct us_data *)__us;
 	struct Scsi_Host *host = us_to_host(us);
+	gfp_t orig_gfp = tsk_get_allowd_gfp(current);

+	tsk_set_allowd_gfp(current, orig_gfp & ~GFP_IOFS);
 	for (;;) {
 		US_DEBUGP("*** thread sleeping.\n");
 		if (wait_for_completion_interruptible(&us->cmnd_ready))
@@ -404,6 +406,7 @@ SkipForAbort:
 		/* unlock the device pointers */
 		mutex_unlock(&us->dev_mutex);
 	} /* for (;;) */
+	tsk_set_allowd_gfp(current, orig_gfp);

 	/* Wait until we are told to stop */
 	for (;;) {


Thanks,
-- 
Ming Lei
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux