From: Stephen Hemminger <shemminger@vyatta.com>
To: Jeff Garzik <jgarzik@pobox.com>, Samuel Chessman <chessman@tux.org>
Cc: netdev@vger.kernel.org
Subject: [PATCH 5/7] tlan: manage rx allocation failure better
Date: Fri, 30 May 2008 09:49:56 -0700 [thread overview]
Message-ID: <20080530165033.768240631@vyatta.com> (raw)
In-Reply-To: 20080530164951.033143725@vyatta.com
[-- Attachment #1: tlan-alloc-fail.patch --]
[-- Type: text/plain, Size: 4108 bytes --]
Rx allocation failure at runtime is non-fatal. For normal Rx frame, it
just reuses the buffer, and during setup it just continues with a smaller
receive buffer pool.
Compile tested only.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/drivers/net/tlan.c 2008-05-30 09:25:55.000000000 -0700
+++ b/drivers/net/tlan.c 2008-05-30 09:26:36.000000000 -0700
@@ -1539,8 +1539,6 @@ static u32 TLan_HandleRxEOF( struct net_
TLanList *head_list;
struct sk_buff *skb;
TLanList *tail_list;
- void *t;
- u32 frameSize;
u16 tmpCStat;
dma_addr_t head_list_phys;
@@ -1549,40 +1547,34 @@ static u32 TLan_HandleRxEOF( struct net_
head_list_phys = priv->rxListDMA + sizeof(TLanList) * priv->rxHead;
while (((tmpCStat = head_list->cStat) & TLAN_CSTAT_FRM_CMP) && (ack < 255)) {
- frameSize = head_list->frameSize;
+ dma_addr_t frameDma = head_list->buffer[0].address;
+ u32 frameSize = head_list->frameSize;
ack++;
if (tmpCStat & TLAN_CSTAT_EOC)
eoc = 1;
if (bbuf) {
- skb = dev_alloc_skb(frameSize + 7);
- if (skb == NULL)
- printk(KERN_INFO "TLAN: Couldn't allocate memory for received data.\n");
- else {
+ skb = netdev_alloc_skb(dev, frameSize + 7);
+ if ( skb ) {
head_buffer = priv->rxBuffer + (priv->rxHead * TLAN_MAX_FRAME_SIZE);
skb_reserve(skb, 2);
- t = (void *) skb_put(skb, frameSize);
-
- dev->stats.rx_bytes += head_list->frameSize;
+ pci_dma_sync_single_for_cpu(priv->pciDev,
+ frameDma, frameSize,
+ PCI_DMA_FROMDEVICE);
+ skb_copy_from_linear_data(skb, head_buffer, frameSize);
+ skb_put(skb, frameSize);
+ dev->stats.rx_bytes += frameSize;
- memcpy( t, head_buffer, frameSize );
skb->protocol = eth_type_trans( skb, dev );
netif_rx( skb );
}
} else {
struct sk_buff *new_skb;
- /*
- * I changed the algorithm here. What we now do
- * is allocate the new frame. If this fails we
- * simply recycle the frame.
- */
-
- new_skb = dev_alloc_skb( TLAN_MAX_FRAME_SIZE + 7 );
-
- if ( new_skb != NULL ) {
+ new_skb = netdev_alloc_skb(dev, TLAN_MAX_FRAME_SIZE + 7 );
+ if ( new_skb ) {
skb = TLan_GetSKB(head_list);
- pci_unmap_single(priv->pciDev, head_list->buffer[0].address, TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
+ pci_unmap_single(priv->pciDev, frameDma, TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
skb_put( skb, frameSize );
dev->stats.rx_bytes += frameSize;
@@ -1590,12 +1582,12 @@ static u32 TLan_HandleRxEOF( struct net_
skb->protocol = eth_type_trans( skb, dev );
netif_rx( skb );
- skb_reserve( new_skb, 2 );
+ skb_reserve( new_skb, NET_IP_ALIGN );
head_list->buffer[0].address = pci_map_single(priv->pciDev, new_skb->data, TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
TLan_StoreSKB(head_list, new_skb);
- } else
- printk(KERN_WARNING "TLAN: Couldn't allocate memory for received data.\n" );
+ }
+
}
head_list->forward = 0;
@@ -1994,24 +1986,27 @@ static void TLan_ResetLists( struct net_
if ( bbuf ) {
list->buffer[0].address = priv->rxBufferDMA + ( i * TLAN_MAX_FRAME_SIZE );
} else {
- skb = dev_alloc_skb( TLAN_MAX_FRAME_SIZE + 7 );
- if ( skb == NULL ) {
+ skb = netdev_alloc_skb(dev, TLAN_MAX_FRAME_SIZE + 7 );
+ if ( !skb ) {
printk( "TLAN: Couldn't allocate memory for received data.\n" );
- /* If this ever happened it would be a problem */
- } else {
- skb->dev = dev;
- skb_reserve( skb, 2 );
+ break;
}
+
+ skb_reserve( skb, NET_IP_ALIGN );
list->buffer[0].address = pci_map_single(priv->pciDev, t, TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
TLan_StoreSKB(list, skb);
}
list->buffer[1].count = 0;
list->buffer[1].address = 0;
- if ( i < TLAN_NUM_RX_LISTS - 1 )
- list->forward = list_phys + sizeof(TLanList);
- else
- list->forward = 0;
+ list->forward = list_phys + sizeof(TLanList);
+ }
+
+ /* in case ran out of memory early, clear bits */
+ while (i < TLAN_NUM_RX_LISTS) {
+ TLan_StoreSKB(priv->rxList + i, NULL);
+ ++i;
}
+ list->forward = 0;
} /* TLan_ResetLists */
--
next prev parent reply other threads:[~2008-05-30 16:53 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-05-30 16:49 [PATCH 0/7] TLAN driver cleanups Stephen Hemminger
2008-05-30 16:49 ` [PATCH 1/7] tlan: get rid of padding buffer Stephen Hemminger
2008-05-31 2:19 ` Jeff Garzik
2008-05-30 16:49 ` [PATCH 2/7] tlan: use netdevice stats Stephen Hemminger
2008-05-30 16:49 ` [PATCH 3/7] tlan: remove unused devName field Stephen Hemminger
2008-05-30 16:49 ` [PATCH 4/7] tlan: 64bit conversion Stephen Hemminger
2008-05-30 16:49 ` Stephen Hemminger [this message]
2008-05-30 16:49 ` [PATCH 6/7] tlan: proper shared IRQ support Stephen Hemminger
2008-05-30 16:49 ` [PATCH 7/7] tlan: wrap source lines Stephen Hemminger
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=20080530165033.768240631@vyatta.com \
--to=shemminger@vyatta.com \
--cc=chessman@tux.org \
--cc=jgarzik@pobox.com \
--cc=netdev@vger.kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.