From patchwork Fri Jul 9 12:25:22 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kulikov Vasiliy X-Patchwork-Id: 58396 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 B9B2FB6F1B for ; Fri, 9 Jul 2010 22:25:46 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755907Ab0GIMZm (ORCPT ); Fri, 9 Jul 2010 08:25:42 -0400 Received: from mail-ew0-f46.google.com ([209.85.215.46]:47850 "EHLO mail-ew0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754752Ab0GIMZl (ORCPT ); Fri, 9 Jul 2010 08:25:41 -0400 Received: by ewy23 with SMTP id 23so457111ewy.19 for ; Fri, 09 Jul 2010 05:25:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:subject:date :message-id:x-mailer; bh=jsDmPtzIjmjVzjL8HbfiRxONVbkAHAbdee0Hv6+Dr/w=; b=HqA2/hrK00Fltzw0ByA/gVCsYIrigGfJJfQgX4Ii9FvLtCFsUzBmxeT6kzudgjFgNT aeAVCUltRlBx+I6Ew6sFm56+EAQ3KKuR0xYJhZwnEBR3PkCXoxtjCe/hXf78p97KDmC2 Tku4T/5JCSFTrqukGV3oINEBI0O3Ru/pEGh6w= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer; b=Q+LY1RsLqLOjZIl4DNporCuMEk+BaoaQfpQRnbb22Mi9L11rSUoh8jucFVVpW3YoqD YPjeIwgEODzWBUdUAlChk7tRzzVWBa7mu9HfnT3R21JCLb4w03ftCBkN060OnVRVv1Gc 6PPVZIeyVEVuBwzV4WL1xWOMkHXaXEbqirH6c= Received: by 10.213.31.133 with SMTP id y5mr8006177ebc.68.1278678339102; Fri, 09 Jul 2010 05:25:39 -0700 (PDT) Received: from localhost ([213.87.80.19]) by mx.google.com with ESMTPS id z55sm7160615eeh.3.2010.07.09.05.25.32 (version=TLSv1/SSLv3 cipher=RC4-MD5); Fri, 09 Jul 2010 05:25:38 -0700 (PDT) From: Kulikov Vasiliy To: kernel-janitors@vger.kernel.org Cc: "David S. Miller" , Jiri Pirko , Stephen Hemminger , Eric Dumazet , =?UTF-8?q?Andr=C3=A9=20Goddard=20Rosa?= , netdev@vger.kernel.org Subject: [PATCH 1/2] 82596: do not panic on out of memory Date: Fri, 9 Jul 2010 16:25:22 +0400 Message-Id: <1278678323-6848-1-git-send-email-segooon@gmail.com> X-Mailer: git-send-email 1.7.0.4 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org If dev_alloc_skb() failed then free already allocated skbs. remove_rx_bufs() can be called multiple times, so set rbd->skb to NULL to avoid double free. remove_rx_bufs() was moved upwards to be seen by init_rx_bufs(). Signed-off-by: Kulikov Vasiliy --- drivers/net/82596.c | 42 ++++++++++++++++++++++++++---------------- 1 files changed, 26 insertions(+), 16 deletions(-) diff --git a/drivers/net/82596.c b/drivers/net/82596.c index dd8dc15..73073d0 100644 --- a/drivers/net/82596.c +++ b/drivers/net/82596.c @@ -525,7 +525,21 @@ static irqreturn_t i596_error(int irq, void *dev_id) } #endif -static inline void init_rx_bufs(struct net_device *dev) +static inline void remove_rx_bufs(struct net_device *dev) +{ + struct i596_private *lp = dev->ml_priv; + struct i596_rbd *rbd; + int i; + + for (i = 0, rbd = lp->rbds; i < rx_ring_size; i++, rbd++) { + if (rbd->skb == NULL) + break; + dev_kfree_skb(rbd->skb); + rbd->skb = NULL; + } +} + +static inline int init_rx_bufs(struct net_device *dev) { struct i596_private *lp = dev->ml_priv; int i; @@ -537,8 +551,11 @@ static inline void init_rx_bufs(struct net_device *dev) for (i = 0, rbd = lp->rbds; i < rx_ring_size; i++, rbd++) { struct sk_buff *skb = dev_alloc_skb(PKT_BUF_SZ); - if (skb == NULL) - panic("82596: alloc_skb() failed"); + if (skb == NULL) { + remove_rx_bufs(dev); + return -ENOMEM; + } + skb->dev = dev; rbd->v_next = rbd+1; rbd->b_next = WSWAPrbd(virt_to_bus(rbd+1)); @@ -574,19 +591,8 @@ static inline void init_rx_bufs(struct net_device *dev) rfd->v_next = lp->rfds; rfd->b_next = WSWAPrfd(virt_to_bus(lp->rfds)); rfd->cmd = CMD_EOL|CMD_FLEX; -} - -static inline void remove_rx_bufs(struct net_device *dev) -{ - struct i596_private *lp = dev->ml_priv; - struct i596_rbd *rbd; - int i; - for (i = 0, rbd = lp->rbds; i < rx_ring_size; i++, rbd++) { - if (rbd->skb == NULL) - break; - dev_kfree_skb(rbd->skb); - } + return 0; } @@ -1013,7 +1019,11 @@ static int i596_open(struct net_device *dev) return -EAGAIN; } #endif - init_rx_bufs(dev); + res = init_rx_bufs(dev); + if (res) { + free_irq(dev->irq, dev); + return res; + } netif_start_queue(dev);