All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] staging: greybus: Convert timers to use timer_setup()
@ 2017-10-24  8:25 Kees Cook
  2017-10-24  9:35 ` Bryan O'Donoghue
  2017-10-24 10:03 ` Dan Carpenter
  0 siblings, 2 replies; 10+ messages in thread
From: Kees Cook @ 2017-10-24  8:25 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Bryan O'Donoghue, Johan Hovold, Alex Elder, greybus-dev,
	devel, linux-kernel

In preparation for unconditionally passing the struct timer_list pointer to
all timer callbacks, switch to using the new timer_setup() and from_timer()
to pass the timer pointer explicitly.

Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Bryan O'Donoghue" <pure.logic@nexus-software.ie>
Cc: Johan Hovold <johan@kernel.org>
Cc: Alex Elder <elder@kernel.org>
Cc: greybus-dev@lists.linaro.org
Cc: devel@driverdev.osuosl.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/staging/greybus/loopback.c  | 14 ++++----------
 drivers/staging/greybus/operation.c |  7 +++----
 2 files changed, 7 insertions(+), 14 deletions(-)

diff --git a/drivers/staging/greybus/loopback.c b/drivers/staging/greybus/loopback.c
index 08e255884206..045aaf81113a 100644
--- a/drivers/staging/greybus/loopback.c
+++ b/drivers/staging/greybus/loopback.c
@@ -572,16 +572,11 @@ static void gb_loopback_async_operation_work(struct work_struct *work)
 	gb_loopback_async_operation_put(op_async);
 }
 
-static void gb_loopback_async_operation_timeout(unsigned long data)
+static void gb_loopback_async_operation_timeout(struct timer_list *t)
 {
-	struct gb_loopback_async_operation *op_async;
-	u16 id = data;
+	struct gb_loopback_async_operation *op_async =
+		from_timer(op_async, t, timer);
 
-	op_async = gb_loopback_operation_find(id);
-	if (!op_async) {
-		pr_err("operation %d not found - time out ?\n", id);
-		return;
-	}
 	schedule_work(&op_async->work);
 }
 
@@ -631,8 +626,7 @@ static int gb_loopback_async_operation(struct gb_loopback *gb, int type,
 	if (ret)
 		goto error;
 
-	setup_timer(&op_async->timer, gb_loopback_async_operation_timeout,
-			(unsigned long)operation->id);
+	timer_setup(&op_async->timer, gb_loopback_async_operation_timeout, 0);
 	op_async->timer.expires = jiffies + gb->jiffy_timeout;
 	add_timer(&op_async->timer);
 
diff --git a/drivers/staging/greybus/operation.c b/drivers/staging/greybus/operation.c
index 3023012808d9..ee4ba3f23bef 100644
--- a/drivers/staging/greybus/operation.c
+++ b/drivers/staging/greybus/operation.c
@@ -294,9 +294,9 @@ static void gb_operation_work(struct work_struct *work)
 	gb_operation_put(operation);
 }
 
-static void gb_operation_timeout(unsigned long arg)
+static void gb_operation_timeout(struct timer_list *t)
 {
-	struct gb_operation *operation = (void *)arg;
+	struct gb_operation *operation = from_timer(operation, t, timer);
 
 	if (gb_operation_result_set(operation, -ETIMEDOUT)) {
 		/*
@@ -541,8 +541,7 @@ gb_operation_create_common(struct gb_connection *connection, u8 type,
 			goto err_request;
 		}
 
-		setup_timer(&operation->timer, gb_operation_timeout,
-			    (unsigned long)operation);
+		timer_setup(&operation->timer, gb_operation_timeout, 0);
 	}
 
 	operation->flags = op_flags;
-- 
2.7.4


-- 
Kees Cook
Pixel Security

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

* Re: [PATCH] staging: greybus: Convert timers to use timer_setup()
  2017-10-24  8:25 [PATCH] staging: greybus: Convert timers to use timer_setup() Kees Cook
@ 2017-10-24  9:35 ` Bryan O'Donoghue
  2017-10-24  9:40   ` Bryan O'Donoghue
  2017-10-24 10:03 ` Dan Carpenter
  1 sibling, 1 reply; 10+ messages in thread
From: Bryan O'Donoghue @ 2017-10-24  9:35 UTC (permalink / raw)
  To: Kees Cook, Greg Kroah-Hartman
  Cc: Johan Hovold, Alex Elder, greybus-dev, devel, linux-kernel

On 24/10/17 09:25, Kees Cook wrote:
> In preparation for unconditionally passing the struct timer_list pointer to
> all timer callbacks, switch to using the new timer_setup() and from_timer()
> to pass the timer pointer explicitly.
> 
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: "Bryan O'Donoghue" <pure.logic@nexus-software.ie>
> Cc: Johan Hovold <johan@kernel.org>
> Cc: Alex Elder <elder@kernel.org>
> Cc: greybus-dev@lists.linaro.org
> Cc: devel@driverdev.osuosl.org
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>   drivers/staging/greybus/loopback.c  | 14 ++++----------
>   drivers/staging/greybus/operation.c |  7 +++----
>   2 files changed, 7 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/staging/greybus/loopback.c b/drivers/staging/greybus/loopback.c
> index 08e255884206..045aaf81113a 100644
> --- a/drivers/staging/greybus/loopback.c
> +++ b/drivers/staging/greybus/loopback.c
> @@ -572,16 +572,11 @@ static void gb_loopback_async_operation_work(struct work_struct *work)
>   	gb_loopback_async_operation_put(op_async);
>   }
>   
> -static void gb_loopback_async_operation_timeout(unsigned long data)
> +static void gb_loopback_async_operation_timeout(struct timer_list *t)
>   {
> -	struct gb_loopback_async_operation *op_async;
> -	u16 id = data;
> +	struct gb_loopback_async_operation *op_async =
> +		from_timer(op_async, t, timer);
>   
> -	op_async = gb_loopback_operation_find(id);
> -	if (!op_async) {
> -		pr_err("operation %d not found - time out ?\n", id);
> -		return;
> -	}

Hi Kees, you need to add

	gb_loopback_async_operation_get(op_async); when dropping the 
gb_loopback_operation_find() call here.

>   	schedule_work(&op_async->work);
>   }
>   
> @@ -631,8 +626,7 @@ static int gb_loopback_async_operation(struct gb_loopback *gb, int type,
>   	if (ret)
>   		goto error;
>   
> -	setup_timer(&op_async->timer, gb_loopback_async_operation_timeout,
> -			(unsigned long)operation->id);
> +	timer_setup(&op_async->timer, gb_loopback_async_operation_timeout, 0);
>   	op_async->timer.expires = jiffies + gb->jiffy_timeout;
>   	add_timer(&op_async->timer);
>   
> diff --git a/drivers/staging/greybus/operation.c b/drivers/staging/greybus/operation.c
> index 3023012808d9..ee4ba3f23bef 100644
> --- a/drivers/staging/greybus/operation.c
> +++ b/drivers/staging/greybus/operation.c
> @@ -294,9 +294,9 @@ static void gb_operation_work(struct work_struct *work)
>   	gb_operation_put(operation);
>   }
>   
> -static void gb_operation_timeout(unsigned long arg)
> +static void gb_operation_timeout(struct timer_list *t)
>   {
> -	struct gb_operation *operation = (void *)arg;
> +	struct gb_operation *operation = from_timer(operation, t, timer);
>   
>   	if (gb_operation_result_set(operation, -ETIMEDOUT)) {
>   		/*
> @@ -541,8 +541,7 @@ gb_operation_create_common(struct gb_connection *connection, u8 type,
>   			goto err_request;
>   		}
>   
> -		setup_timer(&operation->timer, gb_operation_timeout,
> -			    (unsigned long)operation);
> +		timer_setup(&operation->timer, gb_operation_timeout, 0);
>   	}
>   
>   	operation->flags = op_flags;
> 

Other than that, the rest looks good to me and you can add my

Reviewed-by: Bryan O'Donoghue <pure.logic@nexus-software.ie>

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

* Re: [PATCH] staging: greybus: Convert timers to use timer_setup()
  2017-10-24  9:35 ` Bryan O'Donoghue
@ 2017-10-24  9:40   ` Bryan O'Donoghue
  2017-10-24 12:47     ` Kees Cook
  0 siblings, 1 reply; 10+ messages in thread
From: Bryan O'Donoghue @ 2017-10-24  9:40 UTC (permalink / raw)
  To: Kees Cook, Greg Kroah-Hartman
  Cc: Johan Hovold, Alex Elder, greybus-dev, devel, linux-kernel

On 24/10/17 10:35, Bryan O'Donoghue wrote:
> On 24/10/17 09:25, Kees Cook wrote:
>> In preparation for unconditionally passing the struct timer_list 
>> pointer to
>> all timer callbacks, switch to using the new timer_setup() and 
>> from_timer()
>> to pass the timer pointer explicitly.
>>
>> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
>> Cc: "Bryan O'Donoghue" <pure.logic@nexus-software.ie>
>> Cc: Johan Hovold <johan@kernel.org>
>> Cc: Alex Elder <elder@kernel.org>
>> Cc: greybus-dev@lists.linaro.org
>> Cc: devel@driverdev.osuosl.org
>> Signed-off-by: Kees Cook <keescook@chromium.org>
>> ---
>>   drivers/staging/greybus/loopback.c  | 14 ++++----------
>>   drivers/staging/greybus/operation.c |  7 +++----
>>   2 files changed, 7 insertions(+), 14 deletions(-)
>>
>> diff --git a/drivers/staging/greybus/loopback.c 
>> b/drivers/staging/greybus/loopback.c
>> index 08e255884206..045aaf81113a 100644
>> --- a/drivers/staging/greybus/loopback.c
>> +++ b/drivers/staging/greybus/loopback.c
>> @@ -572,16 +572,11 @@ static void 
>> gb_loopback_async_operation_work(struct work_struct *work)
>>       gb_loopback_async_operation_put(op_async);
>>   }
>> -static void gb_loopback_async_operation_timeout(unsigned long data)
>> +static void gb_loopback_async_operation_timeout(struct timer_list *t)
>>   {
>> -    struct gb_loopback_async_operation *op_async;
>> -    u16 id = data;
>> +    struct gb_loopback_async_operation *op_async =
>> +        from_timer(op_async, t, timer);
>> -    op_async = gb_loopback_operation_find(id);
>> -    if (!op_async) {
>> -        pr_err("operation %d not found - time out ?\n", id);
>> -        return;
>> -    }
> 
> Hi Kees, you need to add
> 
>      gb_loopback_async_operation_get(op_async); when dropping the 
> gb_loopback_operation_find() call here.

Actually:

	spin_lock_irqsave(&gb_dev.lock, flags);
	gb_loopback_async_operation_get(op_async);
         spin_unlock_irqrestore(&gb_dev.lock, flags);

---
bod

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

* Re: [PATCH] staging: greybus: Convert timers to use timer_setup()
  2017-10-24  8:25 [PATCH] staging: greybus: Convert timers to use timer_setup() Kees Cook
  2017-10-24  9:35 ` Bryan O'Donoghue
@ 2017-10-24 10:03 ` Dan Carpenter
  2017-10-24 10:07   ` Dan Carpenter
  1 sibling, 1 reply; 10+ messages in thread
From: Dan Carpenter @ 2017-10-24 10:03 UTC (permalink / raw)
  To: Kees Cook
  Cc: Greg Kroah-Hartman, devel, Johan Hovold, linux-kernel, greybus-dev

On Tue, Oct 24, 2017 at 01:25:50AM -0700, Kees Cook wrote:
> In preparation for unconditionally passing the struct timer_list pointer to
> all timer callbacks, switch to using the new timer_setup() and from_timer()
> to pass the timer pointer explicitly.
> 
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: "Bryan O'Donoghue" <pure.logic@nexus-software.ie>
> Cc: Johan Hovold <johan@kernel.org>
> Cc: Alex Elder <elder@kernel.org>
> Cc: greybus-dev@lists.linaro.org
> Cc: devel@driverdev.osuosl.org
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>  drivers/staging/greybus/loopback.c  | 14 ++++----------
>  drivers/staging/greybus/operation.c |  7 +++----
>  2 files changed, 7 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/staging/greybus/loopback.c b/drivers/staging/greybus/loopback.c
> index 08e255884206..045aaf81113a 100644
> --- a/drivers/staging/greybus/loopback.c
> +++ b/drivers/staging/greybus/loopback.c
> @@ -572,16 +572,11 @@ static void gb_loopback_async_operation_work(struct work_struct *work)
>  	gb_loopback_async_operation_put(op_async);
>  }
>  
> -static void gb_loopback_async_operation_timeout(unsigned long data)
> +static void gb_loopback_async_operation_timeout(struct timer_list *t)
>  {
> -	struct gb_loopback_async_operation *op_async;
> -	u16 id = data;
> +	struct gb_loopback_async_operation *op_async =
> +		from_timer(op_async, t, timer);
>  

Since this one needs to be re-sent any way, could you do this instead of
breaking up the line?

	struct gb_loopback_async_operation *op_async;

	op_async = from_timer(op_async, t, timer);

regards,
dan carpenter

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

* Re: [PATCH] staging: greybus: Convert timers to use timer_setup()
  2017-10-24 10:03 ` Dan Carpenter
@ 2017-10-24 10:07   ` Dan Carpenter
  0 siblings, 0 replies; 10+ messages in thread
From: Dan Carpenter @ 2017-10-24 10:07 UTC (permalink / raw)
  To: Kees Cook
  Cc: devel, Greg Kroah-Hartman, greybus-dev, Johan Hovold, linux-kernel

Actually, on further reflection, I don't care.  However you write it is
fine.

regards,
dan carpenter

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

* Re: [PATCH] staging: greybus: Convert timers to use timer_setup()
  2017-10-24  9:40   ` Bryan O'Donoghue
@ 2017-10-24 12:47     ` Kees Cook
  2017-10-24 12:52       ` Bryan O'Donoghue
  0 siblings, 1 reply; 10+ messages in thread
From: Kees Cook @ 2017-10-24 12:47 UTC (permalink / raw)
  To: Bryan O'Donoghue
  Cc: Greg Kroah-Hartman, Johan Hovold, Alex Elder, greybus-dev, devel, LKML

On Tue, Oct 24, 2017 at 2:40 AM, Bryan O'Donoghue
<pure.logic@nexus-software.ie> wrote:
> On 24/10/17 10:35, Bryan O'Donoghue wrote:
>>
>> On 24/10/17 09:25, Kees Cook wrote:
>>>
>>> In preparation for unconditionally passing the struct timer_list pointer
>>> to
>>> all timer callbacks, switch to using the new timer_setup() and
>>> from_timer()
>>> to pass the timer pointer explicitly.
>>>
>>> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
>>> Cc: "Bryan O'Donoghue" <pure.logic@nexus-software.ie>
>>> Cc: Johan Hovold <johan@kernel.org>
>>> Cc: Alex Elder <elder@kernel.org>
>>> Cc: greybus-dev@lists.linaro.org
>>> Cc: devel@driverdev.osuosl.org
>>> Signed-off-by: Kees Cook <keescook@chromium.org>
>>> ---
>>>   drivers/staging/greybus/loopback.c  | 14 ++++----------
>>>   drivers/staging/greybus/operation.c |  7 +++----
>>>   2 files changed, 7 insertions(+), 14 deletions(-)
>>>
>>> diff --git a/drivers/staging/greybus/loopback.c
>>> b/drivers/staging/greybus/loopback.c
>>> index 08e255884206..045aaf81113a 100644
>>> --- a/drivers/staging/greybus/loopback.c
>>> +++ b/drivers/staging/greybus/loopback.c
>>> @@ -572,16 +572,11 @@ static void gb_loopback_async_operation_work(struct
>>> work_struct *work)
>>>       gb_loopback_async_operation_put(op_async);
>>>   }
>>> -static void gb_loopback_async_operation_timeout(unsigned long data)
>>> +static void gb_loopback_async_operation_timeout(struct timer_list *t)
>>>   {
>>> -    struct gb_loopback_async_operation *op_async;
>>> -    u16 id = data;
>>> +    struct gb_loopback_async_operation *op_async =
>>> +        from_timer(op_async, t, timer);
>>> -    op_async = gb_loopback_operation_find(id);
>>> -    if (!op_async) {
>>> -        pr_err("operation %d not found - time out ?\n", id);
>>> -        return;
>>> -    }
>>
>>
>> Hi Kees, you need to add
>>
>>      gb_loopback_async_operation_get(op_async); when dropping the
>> gb_loopback_operation_find() call here.
>
>
> Actually:
>
>         spin_lock_irqsave(&gb_dev.lock, flags);
>         gb_loopback_async_operation_get(op_async);
>         spin_unlock_irqrestore(&gb_dev.lock, flags);

Shouldn't the get/put follow the lifetime of the timer running
instead? It shouldnt' be possible to free the op_async while the timer
is still pending/running.

-Kees

-- 
Kees Cook
Pixel Security

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

* Re: [PATCH] staging: greybus: Convert timers to use timer_setup()
  2017-10-24 12:47     ` Kees Cook
@ 2017-10-24 12:52       ` Bryan O'Donoghue
  2017-10-24 13:14         ` Kees Cook
  0 siblings, 1 reply; 10+ messages in thread
From: Bryan O'Donoghue @ 2017-10-24 12:52 UTC (permalink / raw)
  To: Kees Cook
  Cc: Greg Kroah-Hartman, Johan Hovold, Alex Elder, greybus-dev, devel, LKML

On 24/10/17 13:47, Kees Cook wrote:
> On Tue, Oct 24, 2017 at 2:40 AM, Bryan O'Donoghue
> <pure.logic@nexus-software.ie> wrote:
>> On 24/10/17 10:35, Bryan O'Donoghue wrote:
>>>
>>> On 24/10/17 09:25, Kees Cook wrote:
>>>>
>>>> In preparation for unconditionally passing the struct timer_list pointer
>>>> to
>>>> all timer callbacks, switch to using the new timer_setup() and
>>>> from_timer()
>>>> to pass the timer pointer explicitly.
>>>>
>>>> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
>>>> Cc: "Bryan O'Donoghue" <pure.logic@nexus-software.ie>
>>>> Cc: Johan Hovold <johan@kernel.org>
>>>> Cc: Alex Elder <elder@kernel.org>
>>>> Cc: greybus-dev@lists.linaro.org
>>>> Cc: devel@driverdev.osuosl.org
>>>> Signed-off-by: Kees Cook <keescook@chromium.org>
>>>> ---
>>>>    drivers/staging/greybus/loopback.c  | 14 ++++----------
>>>>    drivers/staging/greybus/operation.c |  7 +++----
>>>>    2 files changed, 7 insertions(+), 14 deletions(-)
>>>>
>>>> diff --git a/drivers/staging/greybus/loopback.c
>>>> b/drivers/staging/greybus/loopback.c
>>>> index 08e255884206..045aaf81113a 100644
>>>> --- a/drivers/staging/greybus/loopback.c
>>>> +++ b/drivers/staging/greybus/loopback.c
>>>> @@ -572,16 +572,11 @@ static void gb_loopback_async_operation_work(struct
>>>> work_struct *work)
>>>>        gb_loopback_async_operation_put(op_async);
>>>>    }
>>>> -static void gb_loopback_async_operation_timeout(unsigned long data)
>>>> +static void gb_loopback_async_operation_timeout(struct timer_list *t)
>>>>    {
>>>> -    struct gb_loopback_async_operation *op_async;
>>>> -    u16 id = data;
>>>> +    struct gb_loopback_async_operation *op_async =
>>>> +        from_timer(op_async, t, timer);
>>>> -    op_async = gb_loopback_operation_find(id);
>>>> -    if (!op_async) {
>>>> -        pr_err("operation %d not found - time out ?\n", id);
>>>> -        return;
>>>> -    }
>>>
>>>
>>> Hi Kees, you need to add
>>>
>>>       gb_loopback_async_operation_get(op_async); when dropping the
>>> gb_loopback_operation_find() call here.
>>
>>
>> Actually:
>>
>>          spin_lock_irqsave(&gb_dev.lock, flags);
>>          gb_loopback_async_operation_get(op_async);
>>          spin_unlock_irqrestore(&gb_dev.lock, flags);
> 
> Shouldn't the get/put follow the lifetime of the timer running
> instead? It shouldnt' be possible to free the op_async while the timer
> is still pending/running.
> 
> -Kees
> 

The timeout timer runs for an operation that never completed but on the 
regular "everything is good" path you end up doing 
del_timer_sync(&op_async->timer); so the timer doesn't run.

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

* Re: [PATCH] staging: greybus: Convert timers to use timer_setup()
  2017-10-24 12:52       ` Bryan O'Donoghue
@ 2017-10-24 13:14         ` Kees Cook
  2017-10-24 13:30           ` Bryan O'Donoghue
  0 siblings, 1 reply; 10+ messages in thread
From: Kees Cook @ 2017-10-24 13:14 UTC (permalink / raw)
  To: Bryan O'Donoghue
  Cc: Greg Kroah-Hartman, Johan Hovold, Alex Elder, greybus-dev, devel, LKML

On Tue, Oct 24, 2017 at 5:52 AM, Bryan O'Donoghue
<pure.logic@nexus-software.ie> wrote:
> On 24/10/17 13:47, Kees Cook wrote:
>>
>> On Tue, Oct 24, 2017 at 2:40 AM, Bryan O'Donoghue
>> <pure.logic@nexus-software.ie> wrote:
>>>
>>> On 24/10/17 10:35, Bryan O'Donoghue wrote:
>>>>
>>>>
>>>> On 24/10/17 09:25, Kees Cook wrote:
>>>>>
>>>>>
>>>>> In preparation for unconditionally passing the struct timer_list
>>>>> pointer
>>>>> to
>>>>> all timer callbacks, switch to using the new timer_setup() and
>>>>> from_timer()
>>>>> to pass the timer pointer explicitly.
>>>>>
>>>>> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
>>>>> Cc: "Bryan O'Donoghue" <pure.logic@nexus-software.ie>
>>>>> Cc: Johan Hovold <johan@kernel.org>
>>>>> Cc: Alex Elder <elder@kernel.org>
>>>>> Cc: greybus-dev@lists.linaro.org
>>>>> Cc: devel@driverdev.osuosl.org
>>>>> Signed-off-by: Kees Cook <keescook@chromium.org>
>>>>> ---
>>>>>    drivers/staging/greybus/loopback.c  | 14 ++++----------
>>>>>    drivers/staging/greybus/operation.c |  7 +++----
>>>>>    2 files changed, 7 insertions(+), 14 deletions(-)
>>>>>
>>>>> diff --git a/drivers/staging/greybus/loopback.c
>>>>> b/drivers/staging/greybus/loopback.c
>>>>> index 08e255884206..045aaf81113a 100644
>>>>> --- a/drivers/staging/greybus/loopback.c
>>>>> +++ b/drivers/staging/greybus/loopback.c
>>>>> @@ -572,16 +572,11 @@ static void
>>>>> gb_loopback_async_operation_work(struct
>>>>> work_struct *work)
>>>>>        gb_loopback_async_operation_put(op_async);
>>>>>    }
>>>>> -static void gb_loopback_async_operation_timeout(unsigned long data)
>>>>> +static void gb_loopback_async_operation_timeout(struct timer_list *t)
>>>>>    {
>>>>> -    struct gb_loopback_async_operation *op_async;
>>>>> -    u16 id = data;
>>>>> +    struct gb_loopback_async_operation *op_async =
>>>>> +        from_timer(op_async, t, timer);
>>>>> -    op_async = gb_loopback_operation_find(id);
>>>>> -    if (!op_async) {
>>>>> -        pr_err("operation %d not found - time out ?\n", id);
>>>>> -        return;
>>>>> -    }
>>>>
>>>>
>>>>
>>>> Hi Kees, you need to add
>>>>
>>>>       gb_loopback_async_operation_get(op_async); when dropping the
>>>> gb_loopback_operation_find() call here.
>>>
>>>
>>>
>>> Actually:
>>>
>>>          spin_lock_irqsave(&gb_dev.lock, flags);
>>>          gb_loopback_async_operation_get(op_async);
>>>          spin_unlock_irqrestore(&gb_dev.lock, flags);
>>
>> Shouldn't the get/put follow the lifetime of the timer running
>> instead? It shouldnt' be possible to free the op_async while the timer
>> is still pending/running.
>
> The timeout timer runs for an operation that never completed but on the
> regular "everything is good" path you end up doing
> del_timer_sync(&op_async->timer); so the timer doesn't run.

As far as I can tell, the get/put is already happening external to the timer:

gb_loopback_async_operation():
...
        op_async = kzalloc(sizeof(*op_async), GFP_KERNEL);
...
        INIT_WORK(&op_async->work, gb_loopback_async_operation_work);
        kref_init(&op_async->kref);
...
        op_async->pending = true;
...
        ret = gb_operation_request_send(operation,
                                        gb_loopback_async_operation_callback,
                                        0,
                                        GFP_KERNEL);
...
        timer_setup(&op_async->timer, gb_loopback_async_operation_timeout, 0);
        op_async->timer.expires = jiffies + gb->jiffy_timeout;
        add_timer(&op_async->timer);


gb_loopback_async_operation_callback(): (run by operation)
...
                op_async->pending = false;
                del_timer_sync(&op_async->timer);
                gb_loopback_async_operation_put(op_async);


gb_loopback_async_operation_work(): (scheduled by timer)
...
                op_async->pending = false;
                gb_loopback_async_operation_put(op_async);

(Doing a get/put in the timer callback itself shouldn't be happening:
it must already be pinned in memory for the callback to run.)

-Kees

-- 
Kees Cook
Pixel Security

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

* Re: [PATCH] staging: greybus: Convert timers to use timer_setup()
  2017-10-24 13:14         ` Kees Cook
@ 2017-10-24 13:30           ` Bryan O'Donoghue
  2017-10-24 14:36             ` Kees Cook
  0 siblings, 1 reply; 10+ messages in thread
From: Bryan O'Donoghue @ 2017-10-24 13:30 UTC (permalink / raw)
  To: Kees Cook
  Cc: Greg Kroah-Hartman, Johan Hovold, Alex Elder, greybus-dev, devel, LKML

On 24/10/17 14:14, Kees Cook wrote:
> On Tue, Oct 24, 2017 at 5:52 AM, Bryan O'Donoghue
> <pure.logic@nexus-software.ie> wrote:
>> On 24/10/17 13:47, Kees Cook wrote:
>>>
>>> On Tue, Oct 24, 2017 at 2:40 AM, Bryan O'Donoghue
>>> <pure.logic@nexus-software.ie> wrote:
>>>>
>>>> On 24/10/17 10:35, Bryan O'Donoghue wrote:
>>>>>
>>>>>
>>>>> On 24/10/17 09:25, Kees Cook wrote:
>>>>>>
>>>>>>
>>>>>> In preparation for unconditionally passing the struct timer_list
>>>>>> pointer
>>>>>> to
>>>>>> all timer callbacks, switch to using the new timer_setup() and
>>>>>> from_timer()
>>>>>> to pass the timer pointer explicitly.
>>>>>>
>>>>>> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
>>>>>> Cc: "Bryan O'Donoghue" <pure.logic@nexus-software.ie>
>>>>>> Cc: Johan Hovold <johan@kernel.org>
>>>>>> Cc: Alex Elder <elder@kernel.org>
>>>>>> Cc: greybus-dev@lists.linaro.org
>>>>>> Cc: devel@driverdev.osuosl.org
>>>>>> Signed-off-by: Kees Cook <keescook@chromium.org>
>>>>>> ---
>>>>>>     drivers/staging/greybus/loopback.c  | 14 ++++----------
>>>>>>     drivers/staging/greybus/operation.c |  7 +++----
>>>>>>     2 files changed, 7 insertions(+), 14 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/staging/greybus/loopback.c
>>>>>> b/drivers/staging/greybus/loopback.c
>>>>>> index 08e255884206..045aaf81113a 100644
>>>>>> --- a/drivers/staging/greybus/loopback.c
>>>>>> +++ b/drivers/staging/greybus/loopback.c
>>>>>> @@ -572,16 +572,11 @@ static void
>>>>>> gb_loopback_async_operation_work(struct
>>>>>> work_struct *work)
>>>>>>         gb_loopback_async_operation_put(op_async);
>>>>>>     }
>>>>>> -static void gb_loopback_async_operation_timeout(unsigned long data)
>>>>>> +static void gb_loopback_async_operation_timeout(struct timer_list *t)
>>>>>>     {
>>>>>> -    struct gb_loopback_async_operation *op_async;
>>>>>> -    u16 id = data;
>>>>>> +    struct gb_loopback_async_operation *op_async =
>>>>>> +        from_timer(op_async, t, timer);
>>>>>> -    op_async = gb_loopback_operation_find(id);
>>>>>> -    if (!op_async) {
>>>>>> -        pr_err("operation %d not found - time out ?\n", id);
>>>>>> -        return;
>>>>>> -    }
>>>>>
>>>>>
>>>>>
>>>>> Hi Kees, you need to add
>>>>>
>>>>>        gb_loopback_async_operation_get(op_async); when dropping the
>>>>> gb_loopback_operation_find() call here.
>>>>
>>>>
>>>>
>>>> Actually:
>>>>
>>>>           spin_lock_irqsave(&gb_dev.lock, flags);
>>>>           gb_loopback_async_operation_get(op_async);
>>>>           spin_unlock_irqrestore(&gb_dev.lock, flags);
>>>
>>> Shouldn't the get/put follow the lifetime of the timer running
>>> instead? It shouldnt' be possible to free the op_async while the timer
>>> is still pending/running.
>>
>> The timeout timer runs for an operation that never completed but on the
>> regular "everything is good" path you end up doing
>> del_timer_sync(&op_async->timer); so the timer doesn't run.
> 
> As far as I can tell, the get/put is already happening external to the timer:
> 
> gb_loopback_async_operation():
> ...
>          op_async = kzalloc(sizeof(*op_async), GFP_KERNEL);
> ...
>          INIT_WORK(&op_async->work, gb_loopback_async_operation_work);
>          kref_init(&op_async->kref);
> ...
>          op_async->pending = true;
> ...
>          ret = gb_operation_request_send(operation,
>                                          gb_loopback_async_operation_callback,
>                                          0,
>                                          GFP_KERNEL);
> ...
>          timer_setup(&op_async->timer, gb_loopback_async_operation_timeout, 0);
>          op_async->timer.expires = jiffies + gb->jiffy_timeout;
>          add_timer(&op_async->timer);
> 
> 
> gb_loopback_async_operation_callback(): (run by operation)
> ...
>                  op_async->pending = false;
>                  del_timer_sync(&op_async->timer);
>                  gb_loopback_async_operation_put(op_async);
> 
> 
> gb_loopback_async_operation_work(): (scheduled by timer)
> ...
>                  op_async->pending = false;
>                  gb_loopback_async_operation_put(op_async);
> 


> (Doing a get/put in the timer callback itself shouldn't be happening:
> it must already be pinned in memory for the callback to run.)

Both gb_loopback_async_operation_callback() and 
(gb_loopback_async_operation_timeout || 
gb_loopback_async_operation_work()) can run in parallel so the get in 
the timer callback means we can let the timer stuff free-run w/r to 
gb_loopback_async_operation_callback() - take a reference indicating we 
still want that object and then let gb_loopback_async_operation_work() run.

---
bod

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

* Re: [PATCH] staging: greybus: Convert timers to use timer_setup()
  2017-10-24 13:30           ` Bryan O'Donoghue
@ 2017-10-24 14:36             ` Kees Cook
  0 siblings, 0 replies; 10+ messages in thread
From: Kees Cook @ 2017-10-24 14:36 UTC (permalink / raw)
  To: Bryan O'Donoghue
  Cc: Greg Kroah-Hartman, Johan Hovold, Alex Elder, greybus-dev, devel, LKML

On Tue, Oct 24, 2017 at 6:30 AM, Bryan O'Donoghue
<pure.logic@nexus-software.ie> wrote:
> On 24/10/17 14:14, Kees Cook wrote:
>>
>> On Tue, Oct 24, 2017 at 5:52 AM, Bryan O'Donoghue
>> <pure.logic@nexus-software.ie> wrote:
>>>
>>> On 24/10/17 13:47, Kees Cook wrote:
>>>>
>>>>
>>>> On Tue, Oct 24, 2017 at 2:40 AM, Bryan O'Donoghue
>>>> <pure.logic@nexus-software.ie> wrote:
>>>>>
>>>>>
>>>>> On 24/10/17 10:35, Bryan O'Donoghue wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 24/10/17 09:25, Kees Cook wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> In preparation for unconditionally passing the struct timer_list
>>>>>>> pointer
>>>>>>> to
>>>>>>> all timer callbacks, switch to using the new timer_setup() and
>>>>>>> from_timer()
>>>>>>> to pass the timer pointer explicitly.
>>>>>>>
>>>>>>> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
>>>>>>> Cc: "Bryan O'Donoghue" <pure.logic@nexus-software.ie>
>>>>>>> Cc: Johan Hovold <johan@kernel.org>
>>>>>>> Cc: Alex Elder <elder@kernel.org>
>>>>>>> Cc: greybus-dev@lists.linaro.org
>>>>>>> Cc: devel@driverdev.osuosl.org
>>>>>>> Signed-off-by: Kees Cook <keescook@chromium.org>
>>>>>>> ---
>>>>>>>     drivers/staging/greybus/loopback.c  | 14 ++++----------
>>>>>>>     drivers/staging/greybus/operation.c |  7 +++----
>>>>>>>     2 files changed, 7 insertions(+), 14 deletions(-)
>>>>>>>
>>>>>>> diff --git a/drivers/staging/greybus/loopback.c
>>>>>>> b/drivers/staging/greybus/loopback.c
>>>>>>> index 08e255884206..045aaf81113a 100644
>>>>>>> --- a/drivers/staging/greybus/loopback.c
>>>>>>> +++ b/drivers/staging/greybus/loopback.c
>>>>>>> @@ -572,16 +572,11 @@ static void
>>>>>>> gb_loopback_async_operation_work(struct
>>>>>>> work_struct *work)
>>>>>>>         gb_loopback_async_operation_put(op_async);
>>>>>>>     }
>>>>>>> -static void gb_loopback_async_operation_timeout(unsigned long data)
>>>>>>> +static void gb_loopback_async_operation_timeout(struct timer_list
>>>>>>> *t)
>>>>>>>     {
>>>>>>> -    struct gb_loopback_async_operation *op_async;
>>>>>>> -    u16 id = data;
>>>>>>> +    struct gb_loopback_async_operation *op_async =
>>>>>>> +        from_timer(op_async, t, timer);
>>>>>>> -    op_async = gb_loopback_operation_find(id);
>>>>>>> -    if (!op_async) {
>>>>>>> -        pr_err("operation %d not found - time out ?\n", id);
>>>>>>> -        return;
>>>>>>> -    }
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> Hi Kees, you need to add
>>>>>>
>>>>>>        gb_loopback_async_operation_get(op_async); when dropping the
>>>>>> gb_loopback_operation_find() call here.
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> Actually:
>>>>>
>>>>>           spin_lock_irqsave(&gb_dev.lock, flags);
>>>>>           gb_loopback_async_operation_get(op_async);
>>>>>           spin_unlock_irqrestore(&gb_dev.lock, flags);
>>>>
>>>>
>>>> Shouldn't the get/put follow the lifetime of the timer running
>>>> instead? It shouldnt' be possible to free the op_async while the timer
>>>> is still pending/running.
>>>
>>>
>>> The timeout timer runs for an operation that never completed but on the
>>> regular "everything is good" path you end up doing
>>> del_timer_sync(&op_async->timer); so the timer doesn't run.
>>
>>
>> As far as I can tell, the get/put is already happening external to the
>> timer:
>>
>> gb_loopback_async_operation():
>> ...
>>          op_async = kzalloc(sizeof(*op_async), GFP_KERNEL);
>> ...
>>          INIT_WORK(&op_async->work, gb_loopback_async_operation_work);
>>          kref_init(&op_async->kref);
>> ...
>>          op_async->pending = true;
>> ...
>>          ret = gb_operation_request_send(operation,
>>
>> gb_loopback_async_operation_callback,
>>                                          0,
>>                                          GFP_KERNEL);
>> ...
>>          timer_setup(&op_async->timer,
>> gb_loopback_async_operation_timeout, 0);
>>          op_async->timer.expires = jiffies + gb->jiffy_timeout;
>>          add_timer(&op_async->timer);
>>
>>
>> gb_loopback_async_operation_callback(): (run by operation)
>> ...
>>                  op_async->pending = false;
>>                  del_timer_sync(&op_async->timer);
>>                  gb_loopback_async_operation_put(op_async);
>>
>>
>> gb_loopback_async_operation_work(): (scheduled by timer)
>> ...
>>                  op_async->pending = false;
>>                  gb_loopback_async_operation_put(op_async);
>>
>
>
>> (Doing a get/put in the timer callback itself shouldn't be happening:
>> it must already be pinned in memory for the callback to run.)
>
>
> Both gb_loopback_async_operation_callback() and
> (gb_loopback_async_operation_timeout || gb_loopback_async_operation_work())
> can run in parallel so the get in the timer callback means we can let the
> timer stuff free-run w/r to gb_loopback_async_operation_callback() - take a
> reference indicating we still want that object and then let
> gb_loopback_async_operation_work() run.

Ah right, we're protecting the scheduled worker thread. I'll send a v2, thanks!

-Kees

-- 
Kees Cook
Pixel Security

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

end of thread, other threads:[~2017-10-24 14:36 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-24  8:25 [PATCH] staging: greybus: Convert timers to use timer_setup() Kees Cook
2017-10-24  9:35 ` Bryan O'Donoghue
2017-10-24  9:40   ` Bryan O'Donoghue
2017-10-24 12:47     ` Kees Cook
2017-10-24 12:52       ` Bryan O'Donoghue
2017-10-24 13:14         ` Kees Cook
2017-10-24 13:30           ` Bryan O'Donoghue
2017-10-24 14:36             ` Kees Cook
2017-10-24 10:03 ` Dan Carpenter
2017-10-24 10:07   ` Dan Carpenter

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.