dvb: siano: free spinlock before schedule()
Subsystems (2)
PATCH 1/1 dvb: siano: free spinlock before schedule()
Calling schedule() holding spinlock with disables irqs is improper. As spinlock protects list coredev->buffers, it can be unlocked untill wakeup. This bug was introduced in a9349315f65cd6a16e8fab1f6cf0fd40f379c4db.
--- drivers/media/dvb/siano/smscoreapi.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-)
drivers/media/dvb/siano/smscoreapi.c +4 -2
@@ -1113,9 +1113,11 @@ struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)*/ prepare_to_wait (&coredev->buffer_mng_waitq, &wait,TASK_INTERRUPTIBLE ); - -if (list_empty (&coredev->buffers)) +if (list_empty (&coredev->buffers)) { +spin_unlock_irqrestore (&coredev->bufferslock, flags);schedule (); +spin_lock_irqsave (&coredev->bufferslock, flags); + }finish_wait (&coredev->buffer_mng_waitq, &wait);
Signature · 1 line
1.7.0.4
Quoted 16 lines · Kulikov Vasiliy
Calling
schedule()holding spinlock with disables irqs is improper. As spinlock protects listcoredev->buffers, it can be unlocked untill wakeup. This bug was introduced ina9349315f65cd6a16e8fab1f6cf0fd40f379c4db.Signed-off-by Kulikov Vasiliy <[email protected]>--- drivers/media/dvb/siano/smscoreapi.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-)drivers/media/dvb/siano/smscoreapi.c +0
-0@@ -1113,9 +1113,11 @@ struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)*/
drivers/media/dvb/siano/smscoreapi.c struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev) · line 1122
Quoted 10 lines
drivers/media/dvb/siano/smscoreapi.c +4
-2prepare_to_wait (&coredev->buffer_mng_waitq, &wait,TASK_INTERRUPTIBLE ); - -if (list_empty (&coredev->buffers)) +if (list_empty (&coredev->buffers)) { +spin_unlock_irqrestore (&coredev->bufferslock, flags);schedule (); +spin_lock_irqsave (&coredev->bufferslock, flags); + }finish_wait (&coredev->buffer_mng_waitq, &wait);
There is a better fix (which fixes the potential NULL dereference):
http://lkml.org/lkml/2010/6/7/175
Richard, could you address the comments there and resend?
regards,
Signature · 1 line
js
On Wed, Jul 28, 2010 at 12:24:39AM +0200, Jiri Slaby wrote:
sorry for seeing this so late, was flooded with email lately.
Quoted 4 lines
There is a better fix (which fixes the potential NULL dereference):
http://lkml.org/lkml/2010/6/7/175Richard, could you address the comments there and resend?
I am running this patch since many weeks (after fixing the compile error obviously). Did not implement your beautification suggestion yet, was doing all kinds of experiments with IR and had plenty of unrelated issues.
Richard
drivers/media/dvb/siano/smscoreapi.c renamed from drivers/media/dvb/siano/smscoreapi.c.rz +12 -17
@@ -1100,31 +1100,26 @@* * @return pointer to descriptor on success, NULL on error. */ -struct smscore_buffer_t *smscore_getbuffer (struct smscore_device_t *coredev) + +struct smscore_buffer_t *get_entry (struct smscore_device_t *coredev) {struct smscore_buffer_t *cb =NULL ;unsigned long flags; -DEFINE_WAIT (wait); -spin_lock_irqsave (&coredev->bufferslock, flags); - -/* This function must return a valid buffer, since the buffer list is -* finite, we check that there is an available buffer, if not, we wait -* until such buffer become available. -*/ - -prepare_to_wait (&coredev->buffer_mng_waitq, &wait,TASK_INTERRUPTIBLE ); - -if (list_empty (&coredev->buffers)) -schedule (); - -finish_wait (&coredev->buffer_mng_waitq, &wait); - +if (!list_empty (&coredev->buffers)) { cb = (struct smscore_buffer_t *) coredev->buffers.next;list_del (&cb->entry); - + }spin_unlock_irqrestore (&coredev->bufferslock, flags); +return cb; +} + +struct smscore_buffer_t *smscore_getbuffer (struct smscore_device_t *coredev) +{ +struct smscore_buffer_t *cb =NULL ; + +wait_event (coredev->buffer_mng_waitq, (cb =get_entry (coredev)));return cb; }
Em 08-08-2010 13:10, Richard Zidlicky escreveu:
Quoted 12 lines · Jiri Slaby
sorry for seeing this so late, was flooded with email lately.
Quoted 4 lines
There is a better fix (which fixes the potential NULL dereference):
http://lkml.org/lkml/2010/6/7/175Richard, could you address the comments there and resend?
I am running this patch since many weeks (after fixing the compile error obviously). Did not implement your beautification suggestion yet, was doing all kinds of experiments with IR and had plenty of unrelated issues.
This patch seems a way better than the previous patch. I've rebased it against the current tree (and fixed the identation).
The only missing issue on it is the lack of your Signed-off-by. Richard, could you please send it to us?
--- drivers/media/dvb/siano/smscoreapi.c | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-)
drivers/media/dvb/siano/smscoreapi.c +13 -18
@@ -1098,31 +1098,26 @@ EXPORT_SYMBOL_GPL(smscore_onresponse);* * @return pointer to descriptor on success, NULL on error. */ -struct smscore_buffer_t *smscore_getbuffer (struct smscore_device_t *coredev) + +struct smscore_buffer_t *get_entry (struct smscore_device_t *coredev) {struct smscore_buffer_t *cb =NULL ;unsigned long flags; -DEFINE_WAIT (wait); -spin_lock_irqsave (&coredev->bufferslock, flags); +if (!list_empty (&coredev->buffers)) { + cb = (struct smscore_buffer_t *) coredev->buffers.next; +list_del (&cb->entry); + } +spin_unlock_irqrestore (&coredev->bufferslock, flags); +return cb; +} -/* This function must return a valid buffer, since the buffer list is -* finite, we check that there is an available buffer, if not, we wait -* until such buffer become available. -*/ - -prepare_to_wait (&coredev->buffer_mng_waitq, &wait,TASK_INTERRUPTIBLE ); - -if (list_empty (&coredev->buffers)) -schedule (); - -finish_wait (&coredev->buffer_mng_waitq, &wait); - - cb = (struct smscore_buffer_t *) coredev->buffers.next; -list_del (&cb->entry); +struct smscore_buffer_t *smscore_getbuffer (struct smscore_device_t *coredev) +{ +struct smscore_buffer_t *cb =NULL ; -spin_unlock_irqrestore (&coredev->bufferslock, flags); +wait_event (coredev->buffer_mng_waitq, (cb =get_entry (coredev)));return cb; }
Quoted 8 lines · Mauro Carvalho Chehab
Em 08-08-2010 13:10, Richard Zidlicky escreveu:
Quoted 7 lines · Jiri Slaby
sorry for seeing this so late, was flooded with email lately.
Quoted 2 lines
There is a better fix (which fixes the potential NULL dereference):
http://lkml.org/lkml/2010/6/7/175
Quoted 8 lines
Quoted 5 lines
Quoted 1 line
Richard, could you address the comments there and resend?
I am running this patch since many weeks (after fixing the compile error obviously). Did not implement your beautification suggestion yet, was doing all kinds of experiments with IR and had plenty of unrelated issues.
This patch seems a way better than the previous patch. I've rebased it against the current tree (and fixed the identation).
thanks for looking at it.
Quoted 2 lines
The only missing issue on it is the lack of your Signed-off-by. Richard, could you please send it to us?
PS: I will be away for a while.
Quoted 52 lines
--- drivers/media/dvb/siano/smscoreapi.c | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-)drivers/media/dvb/siano/smscoreapi.c +13
-18@@ -1098,31 +1098,26 @@ EXPORT_SYMBOL_GPL(smscore_onresponse);* * @return pointer to descriptor on success, NULL on error. */ -struct smscore_buffer_t *smscore_getbuffer (struct smscore_device_t *coredev) + +struct smscore_buffer_t *get_entry (struct smscore_device_t *coredev) {struct smscore_buffer_t *cb =NULL ;unsigned long flags; -DEFINE_WAIT (wait); -spin_lock_irqsave (&coredev->bufferslock, flags); +if (!list_empty (&coredev->buffers)) { + cb = (struct smscore_buffer_t *) coredev->buffers.next; +list_del (&cb->entry); + } +spin_unlock_irqrestore (&coredev->bufferslock, flags); +return cb; +} -/* This function must return a valid buffer, since the buffer list is -* finite, we check that there is an available buffer, if not, we wait -* until such buffer become available. -*/ - -prepare_to_wait (&coredev->buffer_mng_waitq, &wait,TASK_INTERRUPTIBLE ); - -if (list_empty (&coredev->buffers)) -schedule (); - -finish_wait (&coredev->buffer_mng_waitq, &wait); - - cb = (struct smscore_buffer_t *) coredev->buffers.next; -list_del (&cb->entry); +struct smscore_buffer_t *smscore_getbuffer (struct smscore_device_t *coredev) +{ +struct smscore_buffer_t *cb =NULL ; -spin_unlock_irqrestore (&coredev->bufferslock, flags); +wait_event (coredev->buffer_mng_waitq, (cb =get_entry (coredev)));return cb; }