From patchwork Wed Jan 27 15:05:44 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike McCormack X-Patchwork-Id: 43815 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 F368FB7FCE for ; Thu, 28 Jan 2010 02:10:51 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754294Ab0A0PK1 (ORCPT ); Wed, 27 Jan 2010 10:10:27 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754184Ab0A0PKZ (ORCPT ); Wed, 27 Jan 2010 10:10:25 -0500 Received: from mail-px0-f182.google.com ([209.85.216.182]:48312 "EHLO mail-px0-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754174Ab0A0PKW (ORCPT ); Wed, 27 Jan 2010 10:10:22 -0500 Received: by mail-px0-f182.google.com with SMTP id 12so4448801pxi.33 for ; Wed, 27 Jan 2010 07:10:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:sender:message-id:date:from :user-agent:mime-version:to:cc:subject:content-type :content-transfer-encoding; bh=YIRujLrcQ2nhGbjEIQA9LQ7HsvGhEkrvT55tlY1IrYo=; b=JEf2h6Wkfnt7ID6vAbjh1702qFEOYmzsGgOpIwEmn6VDFF+YhPVIxcxHIWm8ZNB8x4 VwXdf4p12qoFV0qcioWwJapraFBhZzJ0XIICRiRJjgPCOnvsvEQncSRvD+5IT0rPruTh HNxWYcfZhOkp/wk4ntq2ebZeq3F95UYvqekKA= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=sender:message-id:date:from:user-agent:mime-version:to:cc:subject :content-type:content-transfer-encoding; b=wsCclDX5wDl0W55CMAjX66iTlkEE5x3KaLzBDZtYYyAo3YMk+PTQnXJ8G8zHdTfIrf +wIdALBxz6k8kU+NhYgMqFjwMMvbJdmJ6meOpiiiuJ3bs/rtTTmqFmA8nZElRAwNTKqQ auWkXRxHYHNk+yjB6Xw0y/zV3QAFOy/RQAaL0= Received: by 10.115.86.36 with SMTP id o36mr6604675wal.142.1264605018723; Wed, 27 Jan 2010 07:10:18 -0800 (PST) Received: from ?192.168.0.103? ([121.168.21.96]) by mx.google.com with ESMTPS id 20sm5555138pzk.13.2010.01.27.07.10.16 (version=SSLv3 cipher=RC4-MD5); Wed, 27 Jan 2010 07:10:17 -0800 (PST) Message-ID: <4B605648.7020705@ring3k.org> Date: Thu, 28 Jan 2010 00:05:44 +0900 From: Mike McCormack User-Agent: Mozilla-Thunderbird 2.0.0.22 (X11/20090706) MIME-Version: 1.0 To: Stephen Hemminger CC: netdev@vger.kernel.org Subject: [PATCH 2/3] sky2: Allocate initial skbs in sky2_alloc_buffers Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Allocating everything in one place means there's a single point of failure in sky2_up, and sky2_rx_start can no longer fail. This also fixes a memory leak in the case that sky2_rx_start fails in the middle of allocating skbs, since any allocated skbs will not be free'd in sky2_up's failure path. Signed-off-by: Mike McCormack --- drivers/net/sky2.c | 42 +++++++++++++++++++++++------------------- 1 files changed, 23 insertions(+), 19 deletions(-) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 2061eb8..a967912 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -1358,7 +1358,7 @@ static inline void sky2_rx_update(struct sky2_port *sky2, unsigned rxq) } /* - * Allocate and setup receiver buffer pool. + * Setup receiver buffer pool. * Normal case this ends up creating one list element for skb * in the receive ring. Worst case if using large MTU and each * allocation falls on a different 64 bit region, that results @@ -1392,22 +1392,10 @@ static int sky2_rx_start(struct sky2_port *sky2) if (!(hw->flags & SKY2_HW_NEW_LE)) rx_set_checksum(sky2); - sky2->rx_data_size = sky2_get_rx_data_size(sky2); - /* Fill Rx ring */ + /* submit Rx ring */ for (i = 0; i < sky2->rx_pending; i++) { re = sky2->rx_ring + i; - - re->skb = sky2_rx_alloc(sky2); - if (!re->skb) - goto nomem; - - if (sky2_rx_map_skb(hw->pdev, re, sky2->rx_data_size)) { - dev_kfree_skb(re->skb); - re->skb = NULL; - goto nomem; - } - sky2_rx_submit(sky2, re); } @@ -1453,14 +1441,12 @@ static int sky2_rx_start(struct sky2_port *sky2) return 0; -nomem: - sky2_rx_clean(sky2); - return -ENOMEM; } static int sky2_alloc_buffers(struct sky2_port *sky2) { struct sky2_hw *hw = sky2->hw; + unsigned i; /* must be power of 2 */ sky2->tx_le = pci_alloc_consistent(hw->pdev, @@ -1486,6 +1472,24 @@ static int sky2_alloc_buffers(struct sky2_port *sky2) if (!sky2->rx_ring) goto nomem; + sky2->rx_data_size = sky2_get_rx_data_size(sky2); + + /* Fill Rx ring */ + for (i = 0; i < sky2->rx_pending; i++) { + struct rx_ring_info *re = sky2->rx_ring + i; + + re->skb = sky2_rx_alloc(sky2); + if (!re->skb) + goto nomem; + + if (sky2_rx_map_skb(hw->pdev, re, sky2->rx_data_size)) { + dev_kfree_skb(re->skb); + re->skb = NULL; + goto nomem; + } + } + + return 0; nomem: return -ENOMEM; @@ -1495,6 +1499,8 @@ static void sky2_free_buffers(struct sky2_port *sky2) { struct sky2_hw *hw = sky2->hw; + sky2_rx_clean(sky2); + if (sky2->rx_le) { pci_free_consistent(hw->pdev, RX_LE_BYTES, sky2->rx_le, sky2->rx_le_map); @@ -1953,8 +1959,6 @@ static int sky2_down(struct net_device *dev) /* Free any pending frames stuck in HW queue */ sky2_tx_complete(sky2, sky2->tx_prod); - sky2_rx_clean(sky2); - sky2_free_buffers(sky2); return 0;