From: Francois Romieu <romieu@fr.zoreil.com>
To: Pekka Enberg <penberg@cs.helsinki.fi>
Cc: David Vrabel <dvrabel@cantab.net>,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
david@pleyades.net
Subject: [PATCH 3/3] ipg: plug leaks in the error path of ipg_nic_open
Date: Tue, 2 May 2006 01:12:06 +0200 [thread overview]
Message-ID: <20060501231206.GD7419@electric-eye.fr.zoreil.com> (raw)
In-Reply-To: <1146506939.23931.2.camel@localhost>
Added ipg_{rx/tx}_clear() to factor out some code.
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
drivers/net/ipg.c | 161 +++++++++++++++++++++++++++++++----------------------
1 files changed, 93 insertions(+), 68 deletions(-)
96f29e9d57f503f1275757f4bbec76c0f7f421fc
diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c
index da0fa22..393b617 100644
--- a/drivers/net/ipg.c
+++ b/drivers/net/ipg.c
@@ -16,6 +16,9 @@
*/
#include <linux/crc32.h>
+#define IPG_RX_RING_BYTES (sizeof(struct RFD) * IPG_RFDLIST_LENGTH)
+#define IPG_TX_RING_BYTES (sizeof(struct TFD) * IPG_TFDLIST_LENGTH)
+
#define JUMBO_FRAME_4k_ONLY
enum {
netdev_io_size = 128
@@ -1485,15 +1488,46 @@ static void ipg_nic_txfree(struct net_de
} while (maxtfdcount != 0);
}
-static int ipg_nic_open(struct net_device *dev)
+static void ipg_rx_clear(struct ipg_nic_private *sp)
{
- /* The IPG NIC Ethernet interface is opened when activated
- * by ifconfig.
- */
+ struct pci_dev *pdev = sp->pdev;
+ unsigned int i;
- int error = 0;
- void __iomem *ioaddr = ipg_ioaddr(dev);
+ for (i = 0; i < IPG_RFDLIST_LENGTH; i++) {
+ if (sp->RxBuff[i]) {
+ struct ipg_dmabuff *desc = sp->RxBuffDMAhandle + i;
+
+ IPG_DEV_KFREE_SKB(sp->RxBuff[i]);
+ sp->RxBuff[i] = NULL;
+ pci_unmap_single(pdev, desc->dmahandle, desc->len,
+ PCI_DMA_FROMDEVICE);
+ }
+ }
+}
+
+static void ipg_tx_clear(struct ipg_nic_private *sp)
+{
+ struct pci_dev *pdev = sp->pdev;
+ unsigned int i;
+
+ for (i = 0; i < IPG_TFDLIST_LENGTH; i++) {
+ if (sp->TxBuff[i]) {
+ struct ipg_dmabuff *desc = sp->TxBuffDMAhandle + i;
+
+ IPG_DEV_KFREE_SKB(sp->TxBuff[i]);
+ sp->TxBuff[i] = NULL;
+ pci_unmap_single(pdev, desc->dmahandle, desc->len,
+ PCI_DMA_TODEVICE);
+ }
+ }
+}
+
+static int ipg_nic_open(struct net_device *dev)
+{
struct ipg_nic_private *sp = netdev_priv(dev);
+ void __iomem *ioaddr = ipg_ioaddr(dev);
+ struct pci_dev *pdev = sp->pdev;
+ int rc;
IPG_DEBUG_MSG("_nic_open\n");
@@ -1508,59 +1542,53 @@ static int ipg_nic_open(struct net_devic
/* Register the interrupt line to be used by the IPG within
* the Linux system.
*/
- if ((error = request_irq(sp->pdev->irq,
- &ipg_interrupt_handler,
- SA_SHIRQ, dev->name, dev)) < 0) {
+ rc = request_irq(pdev->irq, &ipg_interrupt_handler, SA_SHIRQ,
+ dev->name, dev);
+ if (rc < 0) {
printk(KERN_INFO "%s: Error when requesting interrupt.\n",
dev->name);
- return error;
+ goto out;
}
- dev->irq = sp->pdev->irq;
+ dev->irq = pdev->irq;
- sp->RFDList = pci_alloc_consistent(sp->pdev,
- (sizeof(struct RFD) *
- IPG_RFDLIST_LENGTH),
+ rc = -ENOMEM;
+
+ sp->RFDList = pci_alloc_consistent(pdev, IPG_RX_RING_BYTES,
&sp->RFDListDMAhandle);
+ if (!sp->RFDList)
+ goto err_free_irq_0;
- sp->TFDList = pci_alloc_consistent(sp->pdev,
- (sizeof(struct TFD) *
- IPG_TFDLIST_LENGTH),
+ sp->TFDList = pci_alloc_consistent(pdev, IPG_TX_RING_BYTES,
&sp->TFDListDMAhandle);
+ if (!sp->TFDList)
+ goto err_free_rx_1;
- if ((sp->RFDList == NULL) || (sp->TFDList == NULL)) {
- printk(KERN_INFO
- "%s: No memory available for IP1000 RFD and/or TFD lists.\n",
- dev->name);
- return -ENOMEM;
- }
-
- error = init_rfdlist(dev);
- if (error < 0) {
+ rc = init_rfdlist(dev);
+ if (rc < 0) {
printk(KERN_INFO "%s: Error during configuration.\n",
dev->name);
- return error;
+ goto err_free_tx_2;
}
- error = init_tfdlist(dev);
- if (error < 0) {
+ rc = init_tfdlist(dev);
+ if (rc < 0) {
printk(KERN_INFO "%s: Error during configuration.\n",
dev->name);
- return error;
+ goto err_release_rfdlist_3;
}
- /* Configure IPG I/O registers. */
- error = ipg_io_config(dev);
- if (error < 0) {
+ rc = ipg_io_config(dev);
+ if (rc < 0) {
printk(KERN_INFO "%s: Error during configuration.\n",
dev->name);
- return error;
+ goto err_release_tfdlist_4;
}
/* Resolve autonegotiation. */
- if (ipg_config_autoneg(dev) < 0) {
+ if (ipg_config_autoneg(dev) < 0)
printk(KERN_INFO "%s: Auto-negotiation error.\n", dev->name);
- }
+
#ifdef JUMBO_FRAME
/* initialize JUMBO Frame control variable */
sp->Jumbo.FoundStart = 0;
@@ -1575,8 +1603,22 @@ #endif
IPG_MC_TX_ENABLE), ioaddr + IPG_MACCTRL);
netif_start_queue(dev);
+out:
+ return rc;
- return 0;
+err_release_tfdlist_4:
+ ipg_tx_clear(sp);
+err_release_rfdlist_3:
+ ipg_rx_clear(sp);
+err_free_tx_2:
+ pci_free_consistent(pdev, IPG_TX_RING_BYTES, sp->TFDList,
+ sp->TFDListDMAhandle);
+err_free_rx_1:
+ pci_free_consistent(pdev, IPG_RX_RING_BYTES, sp->RFDList,
+ sp->RFDListDMAhandle);
+err_free_irq_0:
+ free_irq(pdev->irq, dev);
+ goto out;
}
static int init_rfdlist(struct net_device *dev)
@@ -1593,13 +1635,16 @@ static int init_rfdlist(struct net_devic
sp->RxBuffNotReady = 0;
for (i = 0; i < IPG_RFDLIST_LENGTH; i++) {
+ if (!sp->RxBuff[i])
+ continue;
+
/* Free any allocated receive buffers. */
pci_unmap_single(sp->pdev,
sp->RxBuffDMAhandle[i].dmahandle,
sp->RxBuffDMAhandle[i].len,
PCI_DMA_FROMDEVICE);
- if (sp->RxBuff[i] != NULL)
- IPG_DEV_KFREE_SKB(sp->RxBuff[i]);
+
+ IPG_DEV_KFREE_SKB(sp->RxBuff[i]);
sp->RxBuff[i] = NULL;
/* Clear out the RFS field. */
@@ -1727,11 +1772,11 @@ static int ipg_get_rxbuff(struct net_dev
static int ipg_nic_stop(struct net_device *dev)
{
- /* Release resources requested by driver open function. */
+ struct ipg_nic_private *sp = netdev_priv(dev);
+ struct pci_dev *pdev = sp->pdev;
int i;
int error;
- struct ipg_nic_private *sp = netdev_priv(dev);
IPG_DEBUG_MSG("_nic_stop\n");
@@ -1752,40 +1797,20 @@ static int ipg_nic_stop(struct net_devic
error = ipg_reset(dev, i);
if (error < 0) {
+ // FIXME FIXME FIXME: giant leak alert
return error;
}
- /* Free all receive buffers. */
- for (i = 0; i < IPG_RFDLIST_LENGTH; i++) {
- pci_unmap_single(sp->pdev,
- sp->RxBuffDMAhandle[i].dmahandle,
- sp->RxBuffDMAhandle[i].len,
- PCI_DMA_FROMDEVICE);
- if (sp->RxBuff[i] != NULL)
- IPG_DEV_KFREE_SKB(sp->RxBuff[i]);
- sp->RxBuff[i] = NULL;
- }
+ ipg_rx_clear(sp);
- /* Free all transmit buffers. */
- for (i = 0; i < IPG_TFDLIST_LENGTH; i++) {
- if (sp->TxBuff[i] != NULL)
- IPG_DEV_KFREE_SKB(sp->TxBuff[i]);
- sp->TxBuff[i] = NULL;
- }
+ ipg_tx_clear(sp);
netif_stop_queue(dev);
- /* Free memory associated with the RFDList. */
- pci_free_consistent(sp->pdev,
- (sizeof(struct RFD) *
- IPG_RFDLIST_LENGTH),
- sp->RFDList, sp->RFDListDMAhandle);
-
- /* Free memory associated with the TFDList. */
- pci_free_consistent(sp->pdev,
- (sizeof(struct TFD) *
- IPG_TFDLIST_LENGTH),
- sp->TFDList, sp->TFDListDMAhandle);
+ pci_free_consistent(pdev, IPG_RX_RING_BYTES, sp->RFDList,
+ sp->RFDListDMAhandle);
+ pci_free_consistent(pdev, IPG_TX_RING_BYTES, sp->TFDList,
+ sp->TFDListDMAhandle);
/* Release interrupt line. */
free_irq(dev->irq, dev);
--
1.3.1
next prev parent reply other threads:[~2006-05-01 23:15 UTC|newest]
Thread overview: 57+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-04-27 14:29 IP1000 gigabit nic driver David Gómez
2006-04-27 18:56 ` Francois Romieu
2006-04-27 22:26 ` David Vrabel
2006-04-28 7:57 ` David Gómez
2006-04-28 10:58 ` Pekka Enberg
2006-04-28 11:37 ` David Gómez
2006-04-28 11:51 ` Pekka J Enberg
2006-04-28 11:59 ` Pekka J Enberg
2006-04-28 15:30 ` David Gómez
2006-04-28 16:08 ` Stephen Hemminger
2006-04-28 21:58 ` David Gómez
[not found] ` <20060428154251.23fcfc41@localhost.localdomain>
2006-04-29 7:30 ` David Gómez
2006-04-29 10:29 ` Pekka Enberg
2006-04-29 10:35 ` Arjan van de Ven
2006-04-29 12:21 ` David Gómez
2006-04-29 20:35 ` Pekka Enberg
2006-04-30 9:26 ` Pekka Enberg
2006-04-30 23:40 ` David Vrabel
2006-05-01 9:31 ` Pekka Enberg
2006-05-03 12:43 ` Andrew Morton
2006-05-03 13:06 ` Pekka J Enberg
2006-05-03 14:15 ` David Vrabel
2006-05-01 9:43 ` Pekka Enberg
2006-05-01 11:32 ` David Vrabel
2006-05-01 18:08 ` Pekka Enberg
2006-05-01 23:10 ` [PATCH 1/3] ipg: removal of unreachable code Francois Romieu
2006-05-02 6:36 ` Pekka J Enberg
2006-05-01 23:10 ` [PATCH 2/3] ipg: leaks in ipg_probe Francois Romieu
2006-05-02 6:41 ` Pekka J Enberg
2006-05-02 18:33 ` Francois Romieu
2006-05-02 19:04 ` Pekka Enberg
2006-05-02 22:30 ` [PATCH] ipg: removing more dead code David Gómez
2006-05-03 13:12 ` Pekka J Enberg
2006-05-03 21:00 ` [PATCH 2/3] ipg: leaks in ipg_probe David Gómez
2006-05-01 23:12 ` Francois Romieu [this message]
2006-05-02 6:45 ` [PATCH 3/3] ipg: plug leaks in the error path of ipg_nic_open Pekka J Enberg
2006-05-02 21:44 ` [PATCH 1/2] ipg: sanitize the pci device table Francois Romieu
2006-05-02 21:45 ` [PATCH 2/2] ipg: redundancy with mii.h Francois Romieu
2006-05-02 21:55 ` Francois Romieu
2006-05-03 6:16 ` Pekka J Enberg
2006-05-03 23:35 ` Francois Romieu
2006-05-04 6:52 ` David Vrabel
2006-05-05 0:24 ` Francois Romieu
2006-05-04 13:44 ` Pekka Enberg
2006-05-04 23:55 ` Francois Romieu
2006-05-20 21:03 ` David Vrabel
2006-05-21 7:23 ` Pekka Enberg
2006-05-21 10:16 ` Francois Romieu
2006-05-22 3:22 ` jesse\(建興\)
2006-05-23 6:50 ` jesse\(建興\)
2006-05-01 20:38 ` IP1000 gigabit nic driver Francois Romieu
2006-05-01 20:41 ` Lennert Buytenhek
2006-05-02 0:36 ` David Vrabel
2006-05-01 19:39 ` David Gómez
2006-04-29 12:58 ` David Vrabel
2006-04-28 11:59 ` Ingo Oeser
2006-04-28 7:54 ` David Gómez
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060501231206.GD7419@electric-eye.fr.zoreil.com \
--to=romieu@fr.zoreil.com \
--cc=david@pleyades.net \
--cc=dvrabel@cantab.net \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=penberg@cs.helsinki.fi \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®