From patchwork Tue Dec 6 22:15:43 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: sjur.brandeland@stericsson.com X-Patchwork-Id: 129832 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 17FC31007D6 for ; Wed, 7 Dec 2011 09:16:09 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755211Ab1LFWQA (ORCPT ); Tue, 6 Dec 2011 17:16:00 -0500 Received: from mail-lpp01m010-f46.google.com ([209.85.215.46]:62580 "EHLO mail-lpp01m010-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754813Ab1LFWP6 (ORCPT ); Tue, 6 Dec 2011 17:15:58 -0500 Received: by mail-lpp01m010-f46.google.com with SMTP id p5so1832667lag.19 for ; Tue, 06 Dec 2011 14:15:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references:mime-version:content-type:content-transfer-encoding; bh=KUJlNJnc7thuAV56UjGVTFDEYRAmXkvcF/AhHT/uhq8=; b=GURakoUt6gj5nGeMiPUZOHFLsnjAIhIUGyTjTV0jgJfnEU5MGr7Z7/skwuYPVOr6TO eZNSO8+eGmQ+beEAxyhhlPcCDMFXFwOZnyhHpVBHovLaTlXgNmh6H2A05bPA5Zv0hjWU VR6kIan+22CbGC/6Dk0MfoWjAGwnuztStGiJs= Received: by 10.152.114.42 with SMTP id jd10mr10210923lab.18.1323209757531; Tue, 06 Dec 2011 14:15:57 -0800 (PST) Received: from localhost.localdomain (cm-188.126.199.228.customer.telag.net. [188.126.199.228]) by mx.google.com with ESMTPS id ni5sm22208120lab.3.2011.12.06.14.15.55 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 06 Dec 2011 14:15:56 -0800 (PST) From: =?UTF-8?q?Sjur=20Br=C3=A6ndeland?= To: netdev@vger.kernel.org, David Miller Cc: =?UTF-8?q?Sjur=20Br=C3=A6ndeland?= Subject: [PATCHv2 net-next 3/4] caif-shm: Bugfixes for caif_shmcore.c Date: Tue, 6 Dec 2011 23:15:43 +0100 Message-Id: <1323209744-9718-3-git-send-email-sjur.brandeland@stericsson.com> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: <1323209744-9718-1-git-send-email-sjur.brandeland@stericsson.com> References: <1323209744-9718-1-git-send-email-sjur.brandeland@stericsson.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Various bugfixes for caif_shmcore.c: - fix deadlocks due to improper usage of spin-lock - add missing spin-lock init - don't call dev_kfree_skb() with irqs disabled, use dev_kfree_skb_irq() instead. - fix potential skb null pointer de-reference. Squashed original patches from: Rabin Vincent Durga Prasada Rao BATHINA Arun Murthy Bibek Basu Signed-off-by: Sjur Brændeland --- Change since v1: - s/dev_kfree_skb_any/dev_kfree_skb_irq/ - fixed two pointer cast warnings drivers/net/caif/caif_shmcore.c | 21 +++++++++++---------- 1 files changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/net/caif/caif_shmcore.c b/drivers/net/caif/caif_shmcore.c index d4b26fb..fd59e37 100644 --- a/drivers/net/caif/caif_shmcore.c +++ b/drivers/net/caif/caif_shmcore.c @@ -238,11 +238,11 @@ int caif_shmdrv_rx_cb(u32 mbx_msg, void *priv) if ((avail_emptybuff > HIGH_WATERMARK) && (!pshm_drv->tx_empty_available)) { pshm_drv->tx_empty_available = 1; + spin_unlock_irqrestore(&pshm_drv->lock, flags); pshm_drv->cfdev.flowctrl (pshm_drv->pshm_dev->pshm_netdev, CAIF_FLOW_ON); - spin_unlock_irqrestore(&pshm_drv->lock, flags); /* Schedule the work queue. if required */ if (!work_pending(&pshm_drv->shm_tx_work)) @@ -285,6 +285,7 @@ static void shm_rx_work_func(struct work_struct *rx_work) list_entry(pshm_drv->rx_full_list.next, struct buf_list, list); list_del_init(&pbuf->list); + spin_unlock_irqrestore(&pshm_drv->lock, flags); /* Retrieve pointer to start of the packet descriptor area. */ pck_desc = (struct shm_pck_desc *) pbuf->desc_vptr; @@ -360,6 +361,7 @@ static void shm_rx_work_func(struct work_struct *rx_work) pck_desc++; } + spin_lock_irqsave(&pshm_drv->lock, flags); list_add_tail(&pbuf->list, &pshm_drv->rx_pend_list); spin_unlock_irqrestore(&pshm_drv->lock, flags); @@ -412,7 +414,6 @@ static void shm_tx_work_func(struct work_struct *tx_work) if (skb == NULL) goto send_msg; - /* Check the available no. of buffers in the empty list */ list_for_each(pos, &pshm_drv->tx_empty_list) avail_emptybuff++; @@ -421,9 +422,11 @@ static void shm_tx_work_func(struct work_struct *tx_work) pshm_drv->tx_empty_available) { /* Update blocking condition. */ pshm_drv->tx_empty_available = 0; + spin_unlock_irqrestore(&pshm_drv->lock, flags); pshm_drv->cfdev.flowctrl (pshm_drv->pshm_dev->pshm_netdev, CAIF_FLOW_OFF); + spin_lock_irqsave(&pshm_drv->lock, flags); } /* * We simply return back to the caller if we do not have space @@ -469,6 +472,8 @@ static void shm_tx_work_func(struct work_struct *tx_work) } skb = skb_dequeue(&pshm_drv->sk_qhead); + if (skb == NULL) + break; /* Copy in CAIF frame. */ skb_copy_bits(skb, 0, pbuf->desc_vptr + pbuf->frm_ofs + SHM_HDR_LEN + @@ -477,7 +482,7 @@ static void shm_tx_work_func(struct work_struct *tx_work) pshm_drv->pshm_dev->pshm_netdev->stats.tx_packets++; pshm_drv->pshm_dev->pshm_netdev->stats.tx_bytes += frmlen; - dev_kfree_skb(skb); + dev_kfree_skb_irq(skb); /* Fill in the shared memory packet descriptor area. */ pck_desc = (struct shm_pck_desc *) (pbuf->desc_vptr); @@ -512,16 +517,11 @@ send_msg: static int shm_netdev_tx(struct sk_buff *skb, struct net_device *shm_netdev) { struct shmdrv_layer *pshm_drv; - unsigned long flags = 0; pshm_drv = netdev_priv(shm_netdev); - spin_lock_irqsave(&pshm_drv->lock, flags); - skb_queue_tail(&pshm_drv->sk_qhead, skb); - spin_unlock_irqrestore(&pshm_drv->lock, flags); - /* Schedule Tx work queue. for deferred processing of skbs*/ if (!work_pending(&pshm_drv->shm_tx_work)) queue_work(pshm_drv->pshm_tx_workqueue, &pshm_drv->shm_tx_work); @@ -606,6 +606,7 @@ int caif_shmcore_probe(struct shmdev_layer *pshm_dev) pshm_drv->shm_rx_addr = pshm_dev->shm_base_addr + (NR_TX_BUF * TX_BUF_SZ); + spin_lock_init(&pshm_drv->lock); INIT_LIST_HEAD(&pshm_drv->tx_empty_list); INIT_LIST_HEAD(&pshm_drv->tx_pend_list); INIT_LIST_HEAD(&pshm_drv->tx_full_list); @@ -640,7 +641,7 @@ int caif_shmcore_probe(struct shmdev_layer *pshm_dev) tx_buf->frm_ofs = SHM_CAIF_FRM_OFS; if (pshm_dev->shm_loopback) - tx_buf->desc_vptr = (char *)tx_buf->phy_addr; + tx_buf->desc_vptr = (unsigned char *)tx_buf->phy_addr; else tx_buf->desc_vptr = ioremap(tx_buf->phy_addr, TX_BUF_SZ); @@ -664,7 +665,7 @@ int caif_shmcore_probe(struct shmdev_layer *pshm_dev) rx_buf->len = RX_BUF_SZ; if (pshm_dev->shm_loopback) - rx_buf->desc_vptr = (char *)rx_buf->phy_addr; + rx_buf->desc_vptr = (unsigned char *)rx_buf->phy_addr; else rx_buf->desc_vptr = ioremap(rx_buf->phy_addr, RX_BUF_SZ);