From patchwork Tue Sep 20 10:32:00 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doron Cohen X-Patchwork-Id: 7892 Received: from mail.tu-berlin.de ([130.149.7.33]) by www.linuxtv.org with esmtp (Exim 4.72) (envelope-from ) id 1R5xQA-0002wy-57; Tue, 20 Sep 2011 12:19:22 +0200 X-tubIT-Incoming-IP: 209.132.180.67 Received: from vger.kernel.org ([209.132.180.67]) by mail.tu-berlin.de (exim-4.75/mailfrontend-2) with esmtp id 1R5xQ9-0005Qg-He; Tue, 20 Sep 2011 12:19:21 +0200 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932167Ab1ITKTT (ORCPT + 5 others); Tue, 20 Sep 2011 06:19:19 -0400 Received: from mr.siano-ms.com ([62.0.79.70]:6301 "EHLO Siano-NV.ser.netvision.net.il" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S932161Ab1ITKTS convert rfc822-to-8bit (ORCPT ); Tue, 20 Sep 2011 06:19:18 -0400 Received: from 172.20.9.6 ([172.20.9.6]) by s-mail.siano-ms.ent ([172.20.1.2]) with Microsoft Exchange Server HTTP-DAV ; Tue, 20 Sep 2011 10:20:47 +0000 Received: from Doron-Ubuntu by S-MAIL; 20 Sep 2011 13:32:01 +0300 Subject: [PATCH 15/17]DVB:Siano drivers - Bug fix - avoid (rare) dead locks causing the driver to hang when module removed. From: Doron Cohen Reply-To: doronc@siano-ms.com To: linux-media@vger.kernel.org Organization: Siano Mobile Silicon Date: Tue, 20 Sep 2011 13:32:00 +0300 Message-ID: <1316514720.5199.93.camel@Doron-Ubuntu> Mime-Version: 1.0 X-Mailer: Evolution 2.32.2 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-PMX-Version: 5.6.1.2065439, Antispam-Engine: 2.7.2.376379, Antispam-Data: 2011.9.20.100915 X-PMX-Spam: Gauge=IIIIIIII, Probability=8%, Report=' MSGID_ADDED_BY_MTA 0.05, BODY_SIZE_3000_3999 0, BODY_SIZE_5000_LESS 0, BODY_SIZE_7000_LESS 0, INVALID_MSGID_NO_FQDN 0, __ANY_URI 0, __CP_URI_IN_BODY 0, __CT 0, __CTE 0, __CT_TEXT_PLAIN 0, __DATE_TZ_RU 0, __HAS_MSGID 0, __HAS_X_MAILER 0, __HAS_X_MAILING_LIST 0, __MIME_TEXT_ONLY 0, __MIME_VERSION 0, __SANE_MSGID 0, __TO_MALFORMED_2 0, __TO_NO_NAME 0, __URI_NO_WWW 0, __URI_NS ' X-LSpam-Score: 1.0 (+) X-LSpam-Report: No, score=1.0 required=5.0 tests=BAYES_00=-1.9, KB_DATE_CONTAINS_TAB=2.751, RCVD_IN_DNSWL_MED=-2.3, TAB_IN_FROM=2.494 autolearn=no Hi, This patch step is a Bug fix - avoid (rare) dead locks causing the driver to hang when module removed. Thanks, Doron Cohen ----------------------- From ad75d9ce48d440c6db6c5147530f1e23de2fcb28 Mon Sep 17 00:00:00 2001 From: Doron Cohen Date: Tue, 20 Sep 2011 08:46:52 +0300 Subject: [PATCH 19/21] Bug fix - waiting for free buffers might have caused dead locks. Mechanism changed so locks are released around each wait. --- drivers/media/dvb/siano/smscoreapi.c | 53 +++++++++++++++++++++++++++------ 1 files changed, 43 insertions(+), 10 deletions(-) + list_del(&cb->entry); - wait_event(coredev->buffer_mng_waitq, (cb = get_entry(coredev))); + spin_unlock_irqrestore(&coredev->bufferslock, flags); return cb; } diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index bb92351..0555a38 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -1543,26 +1543,59 @@ EXPORT_SYMBOL_GPL(smscore_onresponse); * * @return pointer to descriptor on success, NULL on error. */ - -struct smscore_buffer_t *get_entry(struct smscore_device_t *coredev) +struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev) { struct smscore_buffer_t *cb = NULL; unsigned long flags; + DEFINE_WAIT(wait); + + spin_lock_irqsave(&coredev->bufferslock, flags); + + /* set the current process state to interruptible sleep + * in case schedule() will be called, this process will go to sleep + * and woken up only when a new buffer is available (see smscore_putbuffer) + */ + prepare_to_wait(&coredev->buffer_mng_waitq, &wait, TASK_INTERRUPTIBLE); + + if (list_empty(&coredev->buffers)) { + sms_debug("no avaliable common buffer, need to schedule"); + + /* + * before going to sleep, release the lock + */ + spin_unlock_irqrestore(&coredev->bufferslock, flags); + + schedule(); + + sms_debug("wake up after schedule()"); + + /* + * acquire the lock again + */ spin_lock_irqsave(&coredev->bufferslock, flags); - if (!list_empty(&coredev->buffers)) { - cb = (struct smscore_buffer_t *) coredev->buffers.next; - list_del(&cb->entry); } + + /* + * in case that schedule() was skipped, set the process state to running + */ + finish_wait(&coredev->buffer_mng_waitq, &wait); + + /* + * verify that the list is not empty, since it might have been + * emptied during the sleep + * comment : this sitation can be avoided using spin_unlock_irqrestore_exclusive + */ + if (list_empty(&coredev->buffers)) { + sms_err("failed to allocate buffer, returning NULL"); spin_unlock_irqrestore(&coredev->bufferslock, flags); - return cb; + return NULL; } -struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev) -{ - struct smscore_buffer_t *cb = NULL; + cb = (struct smscore_buffer_t *) coredev->buffers.next;