All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2 RESEND] rtc: rtc-hid-sensor-time: improve error handling when rtc register fails
@ 2013-08-01 18:39 Alexander Holler
  2013-08-01 18:39 ` [PATCH 2/2 RESEND] rtc: rtc-hid-sensor-time: enable HID input processing early Alexander Holler
  0 siblings, 1 reply; 9+ messages in thread
From: Alexander Holler @ 2013-08-01 18:39 UTC (permalink / raw)
  To: linux-kernel; +Cc: Andrew Morton, rtc-linux, Alessandro Zummo, Alexander Holler

Stop processing hid input when registering the RTC fails and handle
a NULL returned from devm_rtc_device_register() as a failure too.

Signed-off-by: Alexander Holler <holler@ahsoftware.de>
---
 drivers/rtc/rtc-hid-sensor-time.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/rtc/rtc-hid-sensor-time.c b/drivers/rtc/rtc-hid-sensor-time.c
index 7273b01..1ab3d13 100644
--- a/drivers/rtc/rtc-hid-sensor-time.c
+++ b/drivers/rtc/rtc-hid-sensor-time.c
@@ -283,9 +283,11 @@ static int hid_time_probe(struct platform_device *pdev)
 					"hid-sensor-time", &hid_time_rtc_ops,
 					THIS_MODULE);
 
-	if (IS_ERR(time_state->rtc)) {
+	if (IS_ERR_OR_NULL(time_state->rtc)) {
+		ret = time_state->rtc ? PTR_ERR(time_state->rtc) : -ENODEV;
+		time_state->rtc = NULL;
+		sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TIME);
 		dev_err(&pdev->dev, "rtc device register failed!\n");
-		return PTR_ERR(time_state->rtc);
 	}
 
 	return ret;
-- 
1.8.1.4


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

* [PATCH 2/2 RESEND] rtc: rtc-hid-sensor-time: enable HID input processing early
  2013-08-01 18:39 [PATCH 1/2 RESEND] rtc: rtc-hid-sensor-time: improve error handling when rtc register fails Alexander Holler
@ 2013-08-01 18:39 ` Alexander Holler
  2013-08-08 22:11   ` Andrew Morton
  0 siblings, 1 reply; 9+ messages in thread
From: Alexander Holler @ 2013-08-01 18:39 UTC (permalink / raw)
  To: linux-kernel; +Cc: Andrew Morton, rtc-linux, Alessandro Zummo, Alexander Holler

Enable the processing of HID input records before the RTC will be registered,
in order to allow the RTC register function to read clock. Without doing
that the clock can only be read after the probe function has finished.

Signed-off-by: Alexander Holler <holler@ahsoftware.de>
---
 drivers/rtc/rtc-hid-sensor-time.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/rtc/rtc-hid-sensor-time.c b/drivers/rtc/rtc-hid-sensor-time.c
index 1ab3d13..1006a62 100644
--- a/drivers/rtc/rtc-hid-sensor-time.c
+++ b/drivers/rtc/rtc-hid-sensor-time.c
@@ -279,11 +279,18 @@ static int hid_time_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	/*
+	 * Enable HID input processing early in order to be able to read the
+	 * clock already in devm_rtc_device_register().
+	 */
+	hid_device_io_start(hsdev->hdev);
+
 	time_state->rtc = devm_rtc_device_register(&pdev->dev,
 					"hid-sensor-time", &hid_time_rtc_ops,
 					THIS_MODULE);
 
 	if (IS_ERR_OR_NULL(time_state->rtc)) {
+		hid_device_io_stop(hsdev->hdev);
 		ret = time_state->rtc ? PTR_ERR(time_state->rtc) : -ENODEV;
 		time_state->rtc = NULL;
 		sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TIME);
-- 
1.8.1.4


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

* Re: [PATCH 2/2 RESEND] rtc: rtc-hid-sensor-time: enable HID input processing early
  2013-08-01 18:39 ` [PATCH 2/2 RESEND] rtc: rtc-hid-sensor-time: enable HID input processing early Alexander Holler
@ 2013-08-08 22:11   ` Andrew Morton
  2013-08-09  9:45     ` [rtc-linux] " Alexander Holler
  0 siblings, 1 reply; 9+ messages in thread
From: Andrew Morton @ 2013-08-08 22:11 UTC (permalink / raw)
  To: Alexander Holler; +Cc: linux-kernel, rtc-linux, Alessandro Zummo

On Thu,  1 Aug 2013 20:39:02 +0200 Alexander Holler <holler@ahsoftware.de> wrote:

> Enable the processing of HID input records before the RTC will be registered,
> in order to allow the RTC register function to read clock. Without doing
> that the clock can only be read after the probe function has finished.
> 
> Signed-off-by: Alexander Holler <holler@ahsoftware.de>
> ---
>  drivers/rtc/rtc-hid-sensor-time.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/rtc/rtc-hid-sensor-time.c b/drivers/rtc/rtc-hid-sensor-time.c
> index 1ab3d13..1006a62 100644
> --- a/drivers/rtc/rtc-hid-sensor-time.c
> +++ b/drivers/rtc/rtc-hid-sensor-time.c
> @@ -279,11 +279,18 @@ static int hid_time_probe(struct platform_device *pdev)
>  		return ret;
>  	}
>  
> +	/*
> +	 * Enable HID input processing early in order to be able to read the
> +	 * clock already in devm_rtc_device_register().
> +	 */
> +	hid_device_io_start(hsdev->hdev);
> +
>  	time_state->rtc = devm_rtc_device_register(&pdev->dev,
>  					"hid-sensor-time", &hid_time_rtc_ops,
>  					THIS_MODULE);
>  
>  	if (IS_ERR_OR_NULL(time_state->rtc)) {
> +		hid_device_io_stop(hsdev->hdev);
>  		ret = time_state->rtc ? PTR_ERR(time_state->rtc) : -ENODEV;
>  		time_state->rtc = NULL;
>  		sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TIME);

Shouldn't now there be a hid_device_io_stop() in hid_time_remove()?

Also, hid_device_io_start() does a weird up() on a
downed-by-someone-else semaphore.  Where was that down() performed in
this case?

Also, your changelog implies that the kernel is already doing this
hid_device_io_start(), only it does it too late.  If that is the case
then will the existing-before-this-patch call to hid_device_io_start()
generate the "io already started" warning?


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

* Re: [rtc-linux] Re: [PATCH 2/2 RESEND] rtc: rtc-hid-sensor-time: enable HID input processing early
  2013-08-08 22:11   ` Andrew Morton
@ 2013-08-09  9:45     ` Alexander Holler
  2013-08-09 11:12       ` Jiri Kosina
  0 siblings, 1 reply; 9+ messages in thread
From: Alexander Holler @ 2013-08-09  9:45 UTC (permalink / raw)
  To: rtc-linux
  Cc: Andrew Morton, linux-kernel, Alessandro Zummo,
	Andrew de los Reyes, Jiri Kosina

Am 09.08.2013 00:11, schrieb Andrew Morton:
> On Thu,  1 Aug 2013 20:39:02 +0200 Alexander Holler <holler@ahsoftware.de> wrote:
>
>> Enable the processing of HID input records before the RTC will be registered,
>> in order to allow the RTC register function to read clock. Without doing
>> that the clock can only be read after the probe function has finished.
>>
>> Signed-off-by: Alexander Holler <holler@ahsoftware.de>
>> ---
>>   drivers/rtc/rtc-hid-sensor-time.c | 7 +++++++
>>   1 file changed, 7 insertions(+)
>>
>> diff --git a/drivers/rtc/rtc-hid-sensor-time.c b/drivers/rtc/rtc-hid-sensor-time.c
>> index 1ab3d13..1006a62 100644
>> --- a/drivers/rtc/rtc-hid-sensor-time.c
>> +++ b/drivers/rtc/rtc-hid-sensor-time.c
>> @@ -279,11 +279,18 @@ static int hid_time_probe(struct platform_device *pdev)
>>   		return ret;
>>   	}
>>
>> +	/*
>> +	 * Enable HID input processing early in order to be able to read the
>> +	 * clock already in devm_rtc_device_register().
>> +	 */
>> +	hid_device_io_start(hsdev->hdev);
>> +
>>   	time_state->rtc = devm_rtc_device_register(&pdev->dev,
>>   					"hid-sensor-time", &hid_time_rtc_ops,
>>   					THIS_MODULE);
>>
>>   	if (IS_ERR_OR_NULL(time_state->rtc)) {
>> +		hid_device_io_stop(hsdev->hdev);
>>   		ret = time_state->rtc ? PTR_ERR(time_state->rtc) : -ENODEV;
>>   		time_state->rtc = NULL;
>>   		sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TIME);
>
> Shouldn't now there be a hid_device_io_stop() in hid_time_remove()?

That isn't how I understood the commit message to commit 
c849a6143bec520aff2a6646518b0d041402428b which introduced that 
functionality in 3.10. But maybe I'm wrong. I haven't looked at the 
underlying code and haven't tested that (very unlikely) error path with 
the new change I made.

> Also, hid_device_io_start() does a weird up() on a
> downed-by-someone-else semaphore.  Where was that down() performed in
> this case?

Uh, don't know, as already said, I haven't looked at the underlying 
code. But I will now do and will enable all mutex/semaphore debug 
options I find. I have to admit, I didn't have tested the change with 
debug options enabled, so if the kernel doesn't cry on wierd uo()'s 
without debug options enabled, I would have missed that.

> Also, your changelog implies that the kernel is already doing this
> hid_device_io_start(), only it does it too late.  If that is the case
> then will the existing-before-this-patch call to hid_device_io_start()
> generate the "io already started" warning?

No, hid_device_io_start() was introduced especially for such cases. I 
need it because devm_rtc_device_register() might want to read the clock, 
but without hid_device_io_start() that only is possible after probe 
finished (therefor not during devm_rtc_device_register()).

Some time later ...

With several debug options enabled I've got (once) the below backtrace 
with the error path enabled (time_state->rtc = NULL instead of 
time_state->rtc = rtc_device_register()).

[    8.007975] rtc_hid_sensor_time HID-SENSOR-2000a0.0: milliseconds 
supported
[    8.015499] rtc_hid_sensor_time HID-SENSOR-2000a0.0: rtc device 
register failed!
(...)
[   65.551939] =================================
[   65.556343] [ INFO: inconsistent lock state ]

To add some more explanations for the trace (below in full without 
times): The device I use does send the time around once every minute as 
an hid input report and this just might have happened here, causing the 
lock warning. What makes me wonder here is that hid-sensor-hub seems to 
receive the input report even after hid_device_io_stop() was called and 
the probe function for the hid device in question (rtc-hid-sensor-time) 
failed with a rc of -ENODEV.

I've added the HID maintainer and the author of the above mentioned 
commit to cc.

I will need some time (hopefully this weekend) to have a deeper look at 
what goes wrong there. Unfortunatley rtc-hid-sensor-time currently seems 
to be the only user of hid_device_io_stop(), so I might have hit a bug 
or did use it wrong.

But nevertheless, the non-error-path does work as expected, at least I 
haven't seen a problem until now.

Regards,

Alexander Holler

----------
=================================
[ INFO: inconsistent lock state ]
3.10.5-dockstar-00038-g03242d1-dirty #408 Not tainted
---------------------------------
inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage.
swapper/0 [HC1[1]:SC0[0]:HE0:SE1] takes:
  (&(&sd->dyn_callback_lock)->rlock){?.+...}, at: [<c02af9f8>] 
sensor_hub_raw_event+0x10c/0x204
{HARDIRQ-ON-W} state was registered at:
   [<c004dba0>] __lock_acquire+0x630/0x18f0
   [<c004f31c>] lock_acquire+0x64/0x78
   [<c039c960>] _raw_spin_lock+0x40/0x50
   [<c02af854>] sensor_hub_register_callback+0x2c/0xc4
   [<c029ce1c>] hid_time_probe+0x2f8/0x36c
   [<c0234c98>] platform_drv_probe+0x14/0x18
   [<c0233d48>] driver_probe_device+0xb4/0x210
   [<c023243c>] bus_for_each_drv+0x48/0x8c
   [<c0233c50>] device_attach+0x68/0x8c
   [<c02332a8>] bus_probe_device+0x28/0xa0
   [<c0231a84>] device_add+0x3d8/0x594
   [<c0235064>] platform_device_add+0x130/0x1c0
   [<c023ca50>] mfd_add_device+0x1d0/0x23c
   [<c023cc38>] mfd_add_devices+0x7c/0xac
   [<c02afeec>] sensor_hub_probe+0x2a0/0x364
   [<c02aa614>] hid_device_probe+0x90/0x128
   [<c0233d48>] driver_probe_device+0xb4/0x210
   [<c023243c>] bus_for_each_drv+0x48/0x8c
   [<c0233c50>] device_attach+0x68/0x8c
   [<c02332a8>] bus_probe_device+0x28/0xa0
   [<c0231a84>] device_add+0x3d8/0x594
   [<c02aa28c>] hid_add_device+0x244/0x29c
   [<c02b1f10>] usbhid_probe+0x368/0x448
   [<c027bc14>] usb_probe_interface+0x13c/0x1e0
   [<c0233d48>] driver_probe_device+0xb4/0x210
   [<c023243c>] bus_for_each_drv+0x48/0x8c
   [<c0233c50>] device_attach+0x68/0x8c
   [<c02332a8>] bus_probe_device+0x28/0xa0
   [<c0231a84>] device_add+0x3d8/0x594
   [<c027a45c>] usb_set_configuration+0x610/0x6bc
   [<c02821d4>] generic_probe+0x3c/0x74
   [<c027bcdc>] usb_probe_device+0x24/0x3c
   [<c0233d48>] driver_probe_device+0xb4/0x210
   [<c023243c>] bus_for_each_drv+0x48/0x8c
   [<c0233c50>] device_attach+0x68/0x8c
   [<c02332a8>] bus_probe_device+0x28/0xa0
   [<c0231a84>] device_add+0x3d8/0x594
   [<c0272c04>] usb_new_device+0x1dc/0x304
   [<c0274050>] hub_thread+0x9c4/0xf70
   [<c0034600>] kthread+0xa0/0xb0
   [<c00090a0>] ret_from_fork+0x14/0x34
irq event stamp: 139814
hardirqs last  enabled at (139811): [<c02a24e8>] 
cpuidle_enter_state+0x50/0x100
hardirqs last disabled at (139812): [<c0008b74>] __irq_svc+0x34/0xa0
softirqs last  enabled at (139814): [<c001d9c8>] irq_enter+0x44/0x64
softirqs last disabled at (139813): [<c001d9bc>] irq_enter+0x38/0x64

  might help us debug this:
  Possible unsafe locking scenario:
        CPU0
        ----
   lock(&(&sd->dyn_callback_lock)->rlock);
   <Interrupt>
     lock(&(&sd->dyn_callback_lock)->rlock);

**

1 lock held by swapper/0:
  #0:  (&(&sd->lock)->rlock){-.....}, at: [<c02af92c>] 
sensor_hub_raw_event+0x40/0x204

:
CPU: 0 PID: 0 Comm: swapper Not tainted 
3.10.5-dockstar-00038-g03242d1-dirty #408
[<c000d670>] (unwind_backtrace+0x0/0xe0) from [<c000b2bc>] 
(show_stack+0x10/0x14)
[<c000b2bc>] (show_stack+0x10/0x14) from [<c0396884>] 
(print_usage_bug.part.25+0x21c/0x284)
[<c0396884>] (print_usage_bug.part.25+0x21c/0x284) from [<c004d34c>] 
(mark_lock+0x438/0x65c)
[<c004d34c>] (mark_lock+0x438/0x65c) from [<c004db24>] 
(__lock_acquire+0x5b4/0x18f0)
[<c004db24>] (__lock_acquire+0x5b4/0x18f0) from [<c004f31c>] 
(lock_acquire+0x64/0x78)
[<c004f31c>] (lock_acquire+0x64/0x78) from [<c039c960>] 
(_raw_spin_lock+0x40/0x50)
[<c039c960>] (_raw_spin_lock+0x40/0x50) from [<c02af9f8>] 
(sensor_hub_raw_event+0x10c/0x204)
[<c02af9f8>] (sensor_hub_raw_event+0x10c/0x204) from [<c02a9a80>] 
(hid_input_report+0x148/0x170)
[<c02a9a80>] (hid_input_report+0x148/0x170) from [<c02b1a18>] 
(hid_irq_in+0x98/0x228)
[<c02b1a18>] (hid_irq_in+0x98/0x228) from [<c0275fa0>] 
(usb_hcd_giveback_urb+0x94/0xf0)
[<c0275fa0>] (usb_hcd_giveback_urb+0x94/0xf0) from [<c0284c7c>] 
(ehci_urb_done+0x6c/0x78)
[<c0284c7c>] (ehci_urb_done+0x6c/0x78) from [<c0287254>] 
(qh_completions+0x310/0x394)
[<c0287254>] (qh_completions+0x310/0x394) from [<c0289550>] 
(ehci_work+0x14c/0x780)
[<c0289550>] (ehci_work+0x14c/0x780) from [<c028a4cc>] 
(ehci_irq+0x21c/0x248)
[<c028a4cc>] (ehci_irq+0x21c/0x248) from [<c0275958>] 
(usb_hcd_irq+0x38/0x6c)
[<c0275958>] (usb_hcd_irq+0x38/0x6c) from [<c00621bc>] 
(handle_irq_event_percpu+0x2c/0x1a4)
[<c00621bc>] (handle_irq_event_percpu+0x2c/0x1a4) from [<c0062370>] 
(handle_irq_event+0x3c/0x5c)
[<c0062370>] (handle_irq_event+0x3c/0x5c) from [<c0064864>] 
(handle_level_irq+0xd0/0xe8)
[<c0064864>] (handle_level_irq+0xd0/0xe8) from [<c0061c40>] 
(generic_handle_irq+0x20/0x30)
[<c0061c40>] (generic_handle_irq+0x20/0x30) from [<c00098e8>] 
(handle_IRQ+0x60/0x84)
[<c00098e8>] (handle_IRQ+0x60/0x84) from [<c0008b78>] (__irq_svc+0x38/0xa0)
[<c0008b78>] (__irq_svc+0x38/0xa0) from [<c02a24f8>] 
(cpuidle_enter_state+0x60/0x100)
[<c02a24f8>] (cpuidle_enter_state+0x60/0x100) from [<c02a2674>] 
(cpuidle_idle_call+0xdc/0x144)
[<c02a2674>] (cpuidle_idle_call+0xdc/0x144) from [<c0009a2c>] 
(arch_cpu_idle+0x8/0x44)
[<c0009a2c>] (arch_cpu_idle+0x8/0x44) from [<c0042ebc>] 
(cpu_startup_entry+0x80/0xec)
[<c0042ebc>] (cpu_startup_entry+0x80/0xec) from [<c050a750>] 
(start_kernel+0x29c/0x2e4)
----------

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

* Re: [rtc-linux] Re: [PATCH 2/2 RESEND] rtc: rtc-hid-sensor-time: enable HID input processing early
  2013-08-09  9:45     ` [rtc-linux] " Alexander Holler
@ 2013-08-09 11:12       ` Jiri Kosina
  2013-08-09 16:21         ` Alexander Holler
  0 siblings, 1 reply; 9+ messages in thread
From: Jiri Kosina @ 2013-08-09 11:12 UTC (permalink / raw)
  To: Alexander Holler
  Cc: rtc-linux, Andrew Morton, linux-kernel, Alessandro Zummo,
	Andrew de los Reyes

On Fri, 9 Aug 2013, Alexander Holler wrote:


> =================================
> [ INFO: inconsistent lock state ]
> 3.10.5-dockstar-00038-g03242d1-dirty #408 Not tainted
> ---------------------------------
> inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage.
> swapper/0 [HC1[1]:SC0[0]:HE0:SE1] takes:
>  (&(&sd->dyn_callback_lock)->rlock){?.+...}, at: [<c02af9f8>]
> sensor_hub_raw_event+0x10c/0x204
> {HARDIRQ-ON-W} state was registered at:

I think you need the patch below. Please let me know if it fixes it.





From: Jiri Kosina <jkosina@suse.cz>
Subject: [PATCH] HID: sensor-hub: make dyn_callback_lock IRQ-safe

dyn_callback_lock is being taken from IRQ context through hid_irq_in() ->
hid_input_report() -> sensor_hub_raw_event() -> sensor_hub_get_callback(),
therefore anyone else acquiring it needs to disable IRQs to disable deadlocks.

Reported-by: Alexander Holler <holler@ahsoftware.de>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
---
 drivers/hid/hid-sensor-hub.c |   24 ++++++++++++++----------
 1 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
index ca749810..b334e50 100644
--- a/drivers/hid/hid-sensor-hub.c
+++ b/drivers/hid/hid-sensor-hub.c
@@ -147,23 +147,24 @@ int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev,
 {
 	struct hid_sensor_hub_callbacks_list *callback;
 	struct sensor_hub_data *pdata = hid_get_drvdata(hsdev->hdev);
+	unsigned long flags;
 
-	spin_lock(&pdata->dyn_callback_lock);
+	spin_lock_irqsave(&pdata->dyn_callback_lock, flags);
 	list_for_each_entry(callback, &pdata->dyn_callback_list, list)
 		if (callback->usage_id == usage_id) {
-			spin_unlock(&pdata->dyn_callback_lock);
+			spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
 			return -EINVAL;
 		}
 	callback = kzalloc(sizeof(*callback), GFP_ATOMIC);
 	if (!callback) {
-		spin_unlock(&pdata->dyn_callback_lock);
+		spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
 		return -ENOMEM;
 	}
 	callback->usage_callback = usage_callback;
 	callback->usage_id = usage_id;
 	callback->priv = NULL;
 	list_add_tail(&callback->list, &pdata->dyn_callback_list);
-	spin_unlock(&pdata->dyn_callback_lock);
+	spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
 
 	return 0;
 }
@@ -174,15 +175,16 @@ int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev,
 {
 	struct hid_sensor_hub_callbacks_list *callback;
 	struct sensor_hub_data *pdata = hid_get_drvdata(hsdev->hdev);
+	unsigned long flags;
 
-	spin_lock(&pdata->dyn_callback_lock);
+	spin_lock_irqsave(&pdata->dyn_callback_lock, flags);
 	list_for_each_entry(callback, &pdata->dyn_callback_list, list)
 		if (callback->usage_id == usage_id) {
 			list_del(&callback->list);
 			kfree(callback);
 			break;
 		}
-	spin_unlock(&pdata->dyn_callback_lock);
+	spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
 
 	return 0;
 }
@@ -359,15 +361,16 @@ static int sensor_hub_suspend(struct hid_device *hdev, pm_message_t message)
 {
 	struct sensor_hub_data *pdata =  hid_get_drvdata(hdev);
 	struct hid_sensor_hub_callbacks_list *callback;
+	unsigned long flags;
 
 	hid_dbg(hdev, " sensor_hub_suspend\n");
-	spin_lock(&pdata->dyn_callback_lock);
+	spin_lock_irqsave(&pdata->dyn_callback_lock, flags);
 	list_for_each_entry(callback, &pdata->dyn_callback_list, list) {
 		if (callback->usage_callback->suspend)
 			callback->usage_callback->suspend(
 					pdata->hsdev, callback->priv);
 	}
-	spin_unlock(&pdata->dyn_callback_lock);
+	spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
 
 	return 0;
 }
@@ -376,15 +379,16 @@ static int sensor_hub_resume(struct hid_device *hdev)
 {
 	struct sensor_hub_data *pdata =  hid_get_drvdata(hdev);
 	struct hid_sensor_hub_callbacks_list *callback;
+	unsigned long flags;
 
 	hid_dbg(hdev, " sensor_hub_resume\n");
-	spin_lock(&pdata->dyn_callback_lock);
+	spin_lock_irqsave(&pdata->dyn_callback_lock, flags);
 	list_for_each_entry(callback, &pdata->dyn_callback_list, list) {
 		if (callback->usage_callback->resume)
 			callback->usage_callback->resume(
 					pdata->hsdev, callback->priv);
 	}
-	spin_unlock(&pdata->dyn_callback_lock);
+	spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
 
 	return 0;
 }

-- 
Jiri Kosina
SUSE Labs

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

* Re: [rtc-linux] Re: [PATCH 2/2 RESEND] rtc: rtc-hid-sensor-time: enable HID input processing early
  2013-08-09 11:12       ` Jiri Kosina
@ 2013-08-09 16:21         ` Alexander Holler
  2013-08-09 16:33           ` Alexander Holler
  0 siblings, 1 reply; 9+ messages in thread
From: Alexander Holler @ 2013-08-09 16:21 UTC (permalink / raw)
  To: Jiri Kosina
  Cc: rtc-linux, Andrew Morton, linux-kernel, Alessandro Zummo,
	Andrew de los Reyes

Am 09.08.2013 13:12, schrieb Jiri Kosina:
> On Fri, 9 Aug 2013, Alexander Holler wrote:
>
>
>> =================================
>> [ INFO: inconsistent lock state ]
>> 3.10.5-dockstar-00038-g03242d1-dirty #408 Not tainted
>> ---------------------------------
>> inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage.
>> swapper/0 [HC1[1]:SC0[0]:HE0:SE1] takes:
>>   (&(&sd->dyn_callback_lock)->rlock){?.+...}, at: [<c02af9f8>]
>> sensor_hub_raw_event+0x10c/0x204
>> {HARDIRQ-ON-W} state was registered at:
>
> I think you need the patch below. Please let me know if it fixes it.

Thanks a lot. That actually fixed the bug I never have seen before and 
the patch might be a candidate for the stable series (even if almost no 
one would see the problem because there don't seem to be many 
hid-sensor-hub users and the bug seems only to be visible with some 
debug options enabled).

Btw, I've lied and that bug happened with the enforced error path as 
well as during normal operation. It seems I have enabled some debug 
option in the kernel, I never had enabled before.

Unfortunaly that doesn't answer Andrew Mortons questions.

I've now also verified if hid-sensor-hub receives an event with 
sensor_hub_raw_event() in the error-path (hid_device_io_stop() called 
and probe() failed), and this still *does* happen. That event (input 
report) doesn't come through hid-sensor-hub to my driver, but I think 
this is because of my call to sensor_hub_remove_callback() which is in 
the error path too.
So I actually wonder why the input report still is reported from the 
hid-subsystem to hid-sensor-hub, even after I've called 
hid_device_io_stop() and probe() failed.
Maybe everything is still ok and I just got confused with the somehow 
complicate interactions between the usb- and hid-subsystem, 
hid-sensor-hub (which uses MFD) and rtc-hid-sensor-time.

I will also have a look if I find the seem to be missing down(), maybe 
that will offer some explanations to what goes on. Unfortunately I still 
don't know the complete path of events, I've stopped reading the source 
after you've told me about the patch from Andrew de los Reyes, beeing 
happy to have found a nice and proper solution (instead of the delayed 
rtc-device registering I did before). ;)

Regards,

Alexander Holler

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

* Re: [rtc-linux] Re: [PATCH 2/2 RESEND] rtc: rtc-hid-sensor-time: enable HID input processing early
  2013-08-09 16:21         ` Alexander Holler
@ 2013-08-09 16:33           ` Alexander Holler
  2013-08-09 17:02             ` David Herrmann
  0 siblings, 1 reply; 9+ messages in thread
From: Alexander Holler @ 2013-08-09 16:33 UTC (permalink / raw)
  To: rtc-linux
  Cc: Jiri Kosina, Andrew Morton, linux-kernel, Alessandro Zummo,
	Andrew de los Reyes

Am 09.08.2013 18:21, schrieb Alexander Holler:
> I've now also verified if hid-sensor-hub receives an event with
> sensor_hub_raw_event() in the error-path (hid_device_io_stop() called
> and probe() failed), and this still *does* happen. That event (input
> report) doesn't come through hid-sensor-hub to my driver, but I think
> this is because of my call to sensor_hub_remove_callback() which is in
> the error path too.
> So I actually wonder why the input report still is reported from the
> hid-subsystem to hid-sensor-hub, even after I've called
> hid_device_io_stop() and probe() failed.
> Maybe everything is still ok and I just got confused with the somehow
> complicate interactions between the usb- and hid-subsystem,
> hid-sensor-hub (which uses MFD) and rtc-hid-sensor-time.

Adding some more stuff to the confusion: Currently I think it is correct 
that hid-sensor-hub still receives the event, even after 
rtc-hid-sensor-time called hid_device_io_stop() and probe() failed. The 
reason the same reason, why hid-sensor-hub uses mfd, the actual hardware 
device might be shared by different drivers (therfor -hub).

Regards,

Alexander Holler

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

* Re: [rtc-linux] Re: [PATCH 2/2 RESEND] rtc: rtc-hid-sensor-time: enable HID input processing early
  2013-08-09 16:33           ` Alexander Holler
@ 2013-08-09 17:02             ` David Herrmann
  2013-08-09 17:10               ` Alexander Holler
  0 siblings, 1 reply; 9+ messages in thread
From: David Herrmann @ 2013-08-09 17:02 UTC (permalink / raw)
  To: Alexander Holler
  Cc: rtc-linux, Jiri Kosina, Andrew Morton, linux-kernel,
	Alessandro Zummo, Andrew de los Reyes

Hi Alexander

On Fri, Aug 9, 2013 at 6:33 PM, Alexander Holler <holler@ahsoftware.de> wrote:
> Am 09.08.2013 18:21, schrieb Alexander Holler:
>
>> I've now also verified if hid-sensor-hub receives an event with
>> sensor_hub_raw_event() in the error-path (hid_device_io_stop() called
>> and probe() failed), and this still *does* happen. That event (input
>> report) doesn't come through hid-sensor-hub to my driver, but I think
>> this is because of my call to sensor_hub_remove_callback() which is in
>> the error path too.
>> So I actually wonder why the input report still is reported from the
>> hid-subsystem to hid-sensor-hub, even after I've called
>> hid_device_io_stop() and probe() failed.
>> Maybe everything is still ok and I just got confused with the somehow
>> complicate interactions between the usb- and hid-subsystem,
>> hid-sensor-hub (which uses MFD) and rtc-hid-sensor-time.
>
>
> Adding some more stuff to the confusion: Currently I think it is correct
> that hid-sensor-hub still receives the event, even after rtc-hid-sensor-time
> called hid_device_io_stop() and probe() failed. The reason the same reason,
> why hid-sensor-hub uses mfd, the actual hardware device might be shared by
> different drivers (therfor -hub).

I don't have time right know to debug this, but I thought I'd just
clarify how the HID I/O lock works:

HID core uses a semaphore to protect driver probe and removal. That
is, the semaphore is locked during the ->probe() and ->remove()
callbacks. The input event handler (in atomic context!) tries to lock
this, too. If it fails due to ->probe or ->remove currently running,
it simply drops the input events (which is fine for reasons that don't
matter here). If it can lock it, it simply calls the ->raw_event() or
whatever callbacks of the driver (probably via hid-input).
If no driver is currently bound to a device, all input events are
always dropped.

If a driver now needs to perform I/O during ->probe or ->remove, they
must explicitly notify HID core about this. We cannot allow it
automatically as drivers must have a chance to setup some context
before the first events are passed in.
We start I/O via hid_device_io_start(). This simply releases the
->probe() semaphore and makes sure HID core knows about this. Once you
call it, your drivers input callbacks will be used by HID core so you
can perform I/O. Once you call hid_device_io_stop() the semaphore is
locked again and no more I/O is possible.

Same applies to the ->remove() callback, although it's not used by any
driver, yet. The reason is that ->remove() is almost always called if
the transport layer is already closed so any I/O will return -EIO.

We make sure we don't do any double down() or up() by tracking it via
a boolean. The memory barriers there aren't really obvious but it
should be correct.

I hope that explains how all this works. I can look over your patch on
Sunday if still necessary.

Cheers
David

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

* Re: [rtc-linux] Re: [PATCH 2/2 RESEND] rtc: rtc-hid-sensor-time: enable HID input processing early
  2013-08-09 17:02             ` David Herrmann
@ 2013-08-09 17:10               ` Alexander Holler
  0 siblings, 0 replies; 9+ messages in thread
From: Alexander Holler @ 2013-08-09 17:10 UTC (permalink / raw)
  To: David Herrmann
  Cc: rtc-linux, Jiri Kosina, Andrew Morton, linux-kernel,
	Alessandro Zummo, Andrew de los Reyes

Am 09.08.2013 19:02, schrieb David Herrmann:

> I hope that explains how all this works. I can look over your patch on
> Sunday if still necessary.

Thanks a lot for the explanation. Actually I don't have a problem but 
Andrew Morton asked me some questions I can't answer without looking in 
someone else source. ;)

Fortunately that forced me to enable some debug options which have shown 
a bug Jiri fixed right after I've reported it.

So if your explanation answered Andrew Morton questions, I'm fine, 
because my driver still works as I think it should. ;)

Thanks again,

Alexander Holler


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

end of thread, other threads:[~2013-08-09 17:11 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-01 18:39 [PATCH 1/2 RESEND] rtc: rtc-hid-sensor-time: improve error handling when rtc register fails Alexander Holler
2013-08-01 18:39 ` [PATCH 2/2 RESEND] rtc: rtc-hid-sensor-time: enable HID input processing early Alexander Holler
2013-08-08 22:11   ` Andrew Morton
2013-08-09  9:45     ` [rtc-linux] " Alexander Holler
2013-08-09 11:12       ` Jiri Kosina
2013-08-09 16:21         ` Alexander Holler
2013-08-09 16:33           ` Alexander Holler
2013-08-09 17:02             ` David Herrmann
2013-08-09 17:10               ` Alexander Holler

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.