Re: [RFC PATCH] ACPI: eject device synchronously

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

 



On Sat, 2008-06-14 at 04:28 +0800, Alok Kataria wrote:
> This is w.r.t some ACPI changes, to fix a deadlock when ejecting a
> cpu.
> In http://bugzilla.kernel.org/show_bug.cgi?id=9772#c31
> Len raises some concerns about a theoretical race. In the current code
> path we
> could return to the userspace without doing the actual eject of the
> device.
> This deferring of device eject and device unregistering was done to
> fix a
> deadlock at cpu eject time.
> 
> IMO, we could do with only deferring the device unregistration part to
> the
> thread. So before we return to the userspace we make sure that we
> execute the
> _PS3 and _EJ0 objects of the device being removed. So the device is
> physically
> removed when the write to the sysfile completes.
Acked-by: Zhang Rui <rui.zhang@xxxxxxxxx>

thanks,
rui
> 
> patch on top of acpi-test.
> --
> VMware, Inc. is providing the following patch to you under the terms
> of the GPL
> version 2 and no later version. This patch is provided as is, with no
> warranties or support. VMware disclaims all liability in connection
> with
> the use/inability to use this patch. Any use of the attached is
> considered acceptance of the above.
> 
> Signed-off-by: Alok N Kataria <akataria@xxxxxxxxxx>
> Cc: Zhang Rui <rui.zhang@xxxxxxxxx>
> 
> Index: linux-2.6/drivers/acpi/scan.c
> ===================================================================
> --- linux-2.6.orig/drivers/acpi/scan.c  2008-06-13 10:51:16.000000000
> -0700
> +++ linux-2.6/drivers/acpi/scan.c       2008-06-13 11:32:14.000000000
> -0700
> @@ -96,14 +96,7 @@
> 
>  static int acpi_bus_hot_remove_device(void *context)
>  {
> -       struct acpi_device *device;
> -       acpi_handle handle = context;
> -       struct acpi_object_list arg_list;
> -       union acpi_object arg;
> -       acpi_status status = AE_OK;
> -
> -       if (acpi_bus_get_device(handle, &device))
> -               return 0;
> +       struct acpi_device *device = context;
> 
>         if (!device)
>                 return 0;
> @@ -118,32 +111,6 @@
>                 return -1;
>         }
> 
> -       /* power off device */
> -       status = acpi_evaluate_object(handle, "_PS3", NULL, NULL);
> -       if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
> -               ACPI_DEBUG_PRINT((ACPI_DB_WARN,
> -                               "Power-off device failed\n"));
> -
> -       if (device->flags.lockable) {
> -               arg_list.count = 1;
> -               arg_list.pointer = &arg;
> -               arg.type = ACPI_TYPE_INTEGER;
> -               arg.integer.value = 0;
> -               acpi_evaluate_object(handle, "_LCK", &arg_list, NULL);
> -       }
> -
> -       arg_list.count = 1;
> -       arg_list.pointer = &arg;
> -       arg.type = ACPI_TYPE_INTEGER;
> -       arg.integer.value = 1;
> -
> -       /*
> -        * TBD: _EJD support.
> -        */
> -       status = acpi_evaluate_object(handle, "_EJ0", &arg_list,
> NULL);
> -       if (ACPI_FAILURE(status))
> -               return -ENODEV;
> -
>         return 0;
>  }
> 
> @@ -153,6 +120,8 @@
>  {
>         int ret = count;
>         acpi_status status;
> +       struct acpi_object_list arg_list;
> +       union acpi_object arg;
>         acpi_object_type type = 0;
>         struct acpi_device *acpi_device = to_acpi_device(d);
>         struct task_struct *task;
> @@ -172,9 +141,37 @@
>                 goto err;
>         }
> 
> -       /* remove the device in another thread to fix the deadlock
> issue */
> +       /* power off device */
> +       status = acpi_evaluate_object(acpi_device->handle, "_PS3",
> NULL, NULL);
> +       if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
> +               ACPI_DEBUG_PRINT((ACPI_DB_WARN,
> +                               "Power-off device failed\n"));
> +
> +       if (acpi_device->flags.lockable) {
> +               arg_list.count = 1;
> +               arg_list.pointer = &arg;
> +               arg.type = ACPI_TYPE_INTEGER;
> +               arg.integer.value = 0;
> +               acpi_evaluate_object(acpi_device->handle,
> +                                       "_LCK", &arg_list, NULL);
> +       }
> +
> +       arg_list.count = 1;
> +       arg_list.pointer = &arg;
> +       arg.type = ACPI_TYPE_INTEGER;
> +       arg.integer.value = 1;
> +
> +       /*
> +        * TBD: _EJD support.
> +        */
> +       status = acpi_evaluate_object(acpi_device->handle,
> +                                       "_EJ0", &arg_list, NULL);
> +       if (ACPI_FAILURE(status))
> +               return -ENODEV;
> +
> +       /* unregister the device in another thread to fix the deadlock
> issue */
>         task = kthread_run(acpi_bus_hot_remove_device,
> -                               acpi_device->handle,
> "acpi_hot_remove_device");
> +                               acpi_device,
> "acpi_hot_remove_device");
>         if (IS_ERR(task))
>                 ret = PTR_ERR(task);
>  err:
> 
> 
> 
> 

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

[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux