From: Pekka Pietikainen <pp@ee.oulu.fi>
To: "David S. Miller" <davem@davemloft.net>
Cc: Andrew Morton <akpm@osdl.org>, netdev@oss.sgi.com
Subject: Re: Fw: b44 ifconfig fails with ENOMEM
Date: Sat, 8 Jan 2005 00:02:33 +0200 [thread overview]
Message-ID: <20050107220233.GA9639@ee.oulu.fi> (raw)
In-Reply-To: <20050104142026.000be2e8.davem@davemloft.net>
On Tue, Jan 04, 2005 at 02:20:26PM -0800, David S. Miller wrote:
> On Mon, 3 Jan 2005 19:18:36 -0800
> Andrew Morton <akpm@osdl.org> wrote:
>
> > b44 requires an order-8 allocation? Good luck...
>
> Yes, it allocates a full TX ring worth of bounce buffers
> to work around a DMA addressing limitation. It should do
> a bunch of smaller consistent allocations instead of one
> huge one, that's for sure.
-ENOHARDWARE (Santa got me an Athlon64 with dual GigE) so someone else will
have to pick up the ball. Shouldn't be too difficult, quickly thinking
something like:
X-It-Compiles-Lets-Ship-It: pp@ee.oulu.fi
--- ./b44.c.orig 2005-01-05 12:15:30.000000000 +0200
+++ ./b44.c 2005-01-08 00:00:49.974949992 +0200
@@ -68,6 +68,8 @@
(BP)->tx_cons - (BP)->tx_prod - TX_RING_GAP(BP))
#define NEXT_TX(N) (((N) + 1) & (B44_TX_RING_SIZE - 1))
+#define B44_BOUNCEBUF(ENTRY) (bp->tx_bufs[(ENTRY)&(B44_NUM_BOUNCEBUFS-1)]+((ENTRY)>>B44_BOUNCEBUF_SHIFT)*TX_PKT_BUF_SZ)
+
#define RX_PKT_BUF_SZ (1536 + bp->rx_offset + 64)
#define TX_PKT_BUF_SZ (B44_MAX_MTU + ETH_HLEN + 8)
@@ -927,8 +929,8 @@
if(mapping+len > B44_DMA_MASK) {
/* Chip can't handle DMA to/from >1GB, use bounce buffer */
pci_unmap_single(bp->pdev, mapping, len,PCI_DMA_TODEVICE);
- memcpy(bp->tx_bufs+entry*TX_PKT_BUF_SZ,skb->data,skb->len);
- mapping = pci_map_single(bp->pdev, bp->tx_bufs+entry*TX_PKT_BUF_SZ, len, PCI_DMA_TODEVICE);
+ memcpy(B44_BOUNCEBUF(entry),skb->data,skb->len);
+ mapping = pci_map_single(bp->pdev, B44_BOUNCEBUF(entry), len, PCI_DMA_TODEVICE);
}
bp->tx_buffers[entry].skb = skb;
@@ -1059,6 +1061,7 @@
*/
static void b44_free_consistent(struct b44 *bp)
{
+ int i;
if (bp->rx_buffers) {
kfree(bp->rx_buffers);
bp->rx_buffers = NULL;
@@ -1077,10 +1080,12 @@
bp->tx_ring, bp->tx_ring_dma);
bp->tx_ring = NULL;
}
- if (bp->tx_bufs) {
- pci_free_consistent(bp->pdev, B44_TX_RING_SIZE * TX_PKT_BUF_SZ,
- bp->tx_bufs, bp->tx_bufs_dma);
- bp->tx_bufs = NULL;
+ for(i = 0; i < B44_NUM_BOUNCEBUFS; i++) {
+ if (bp->tx_bufs[i]) {
+ pci_free_consistent(bp->pdev, B44_TX_RING_SIZE * TX_PKT_BUF_SZ / B44_NUM_BOUNCEBUFS,
+ bp->tx_bufs[i], bp->tx_bufs_dma[i]);
+ bp->tx_bufs[i] = NULL;
+ }
}
}
@@ -1090,7 +1095,7 @@
*/
static int b44_alloc_consistent(struct b44 *bp)
{
- int size;
+ int i,size;
size = B44_RX_RING_SIZE * sizeof(struct ring_info);
bp->rx_buffers = kmalloc(size, GFP_KERNEL);
@@ -1104,11 +1109,13 @@
goto out_err;
memset(bp->tx_buffers, 0, size);
- size = B44_TX_RING_SIZE * TX_PKT_BUF_SZ;
- bp->tx_bufs = pci_alloc_consistent(bp->pdev, size, &bp->tx_bufs_dma);
- if (!bp->tx_bufs)
+ size = (B44_TX_RING_SIZE * TX_PKT_BUF_SZ) / B44_NUM_BOUNCEBUFS;
+ for(i = 0; i < B44_NUM_BOUNCEBUFS; i++) {
+ bp->tx_bufs[i] = pci_alloc_consistent(bp->pdev, size, &bp->tx_bufs_dma[i]);
+ if (!bp->tx_bufs[i])
goto out_err;
- memset(bp->tx_bufs, 0, size);
+ memset(bp->tx_bufs[i], 0, size);
+ }
size = DMA_TABLE_BYTES;
bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma);
--- ./b44.h.orig 2005-01-05 12:15:33.000000000 +0200
+++ ./b44.h 2005-01-07 23:53:07.234297264 +0200
@@ -359,6 +359,8 @@
};
#define B44_MCAST_TABLE_SIZE 32
+#define B44_BOUNCEBUF_SHIFT 3
+#define B44_NUM_BOUNCEBUFS (1 << B44_BOUNCEBUF_SHIFT)
/* SW copy of device statistics, kept up to date by periodic timer
* which probes HW values. Must have same relative layout as HW
@@ -397,7 +399,7 @@
struct ring_info *rx_buffers;
struct ring_info *tx_buffers;
- unsigned char *tx_bufs;
+ unsigned char *tx_bufs[B44_NUM_BOUNCEBUFS];
u32 dma_offset;
u32 flags;
@@ -429,7 +431,8 @@
struct pci_dev *pdev;
struct net_device *dev;
- dma_addr_t rx_ring_dma, tx_ring_dma,tx_bufs_dma;
+ dma_addr_t rx_ring_dma, tx_ring_dma;
+ dma_addr_t tx_bufs_dma[B44_NUM_BOUNCEBUFS];
u32 rx_pending;
u32 tx_pending;
next prev parent reply other threads:[~2005-01-07 22:02 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-01-04 3:18 Fw: b44 ifconfig fails with ENOMEM Andrew Morton
2005-01-04 22:20 ` David S. Miller
2005-01-07 22:02 ` Pekka Pietikainen [this message]
2005-01-21 0:32 ` Pekka Pietikainen
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=20050107220233.GA9639@ee.oulu.fi \
--to=pp@ee.oulu.fi \
--cc=akpm@osdl.org \
--cc=davem@davemloft.net \
--cc=netdev@oss.sgi.com \
/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.