* [PATCH 1/2] sky2: align IP header on Rx if possible
@ 2007-11-28 22:27 Stephen Hemminger
2007-11-28 22:50 ` [PATCH 2/2] sky2: rx allocation threshold change Stephen Hemminger
2007-12-01 21:53 ` [PATCH 1/2] sky2: align IP header on Rx if possible Jeff Garzik
0 siblings, 2 replies; 3+ messages in thread
From: Stephen Hemminger @ 2007-11-28 22:27 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev
The sky2 driver was not aligning the IP header on receive buffers.
This workaround is only needed on hardware with broken FIFO, newer chips
without FIFO can just DMA to unaligned address.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
---
Please apply for 2.6.25 this is not urgent.
--- a/drivers/net/sky2.c 2007-11-26 16:30:57.000000000 -0800
+++ b/drivers/net/sky2.c 2007-11-26 17:18:27.000000000 -0800
@@ -64,7 +64,6 @@
#define RX_LE_BYTES (RX_LE_SIZE*sizeof(struct sky2_rx_le))
#define RX_MAX_PENDING (RX_LE_SIZE/6 - 2)
#define RX_DEF_PENDING RX_MAX_PENDING
-#define RX_SKB_ALIGN 8
#define TX_RING_SIZE 512
#define TX_DEF_PENDING (TX_RING_SIZE - 1)
@@ -1171,24 +1170,32 @@ static void sky2_vlan_rx_register(struct
/*
* Allocate an skb for receiving. If the MTU is large enough
* make the skb non-linear with a fragment list of pages.
- *
- * It appears the hardware has a bug in the FIFO logic that
- * cause it to hang if the FIFO gets overrun and the receive buffer
- * is not 64 byte aligned. The buffer returned from netdev_alloc_skb is
- * aligned except if slab debugging is enabled.
*/
static struct sk_buff *sky2_rx_alloc(struct sky2_port *sky2)
{
struct sk_buff *skb;
- unsigned long p;
int i;
- skb = netdev_alloc_skb(sky2->netdev, sky2->rx_data_size + RX_SKB_ALIGN);
- if (!skb)
- goto nomem;
-
- p = (unsigned long) skb->data;
- skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p);
+ if (sky2->hw->flags & SKY2_HW_FIFO_HANG_CHECK) {
+ unsigned char *start;
+ /*
+ * Workaround for a bug in FIFO that cause hang
+ * if the FIFO if the receive buffer is not 64 byte aligned.
+ * The buffer returned from netdev_alloc_skb is
+ * aligned except if slab debugging is enabled.
+ */
+ skb = netdev_alloc_skb(sky2->netdev, sky2->rx_data_size + 8);
+ if (!skb)
+ goto nomem;
+ start = PTR_ALIGN(skb->data, 8);
+ skb_reserve(skb, start - skb->data);
+ } else {
+ skb = netdev_alloc_skb(sky2->netdev,
+ sky2->rx_data_size + NET_IP_ALIGN);
+ if (!skb)
+ goto nomem;
+ skb_reserve(skb, NET_IP_ALIGN);
+ }
for (i = 0; i < sky2->rx_nfrags; i++) {
struct page *page = alloc_page(GFP_ATOMIC);
^ permalink raw reply [flat|nested] 3+ messages in thread* [PATCH 2/2] sky2: rx allocation threshold change
2007-11-28 22:27 [PATCH 1/2] sky2: align IP header on Rx if possible Stephen Hemminger
@ 2007-11-28 22:50 ` Stephen Hemminger
2007-12-01 21:53 ` [PATCH 1/2] sky2: align IP header on Rx if possible Jeff Garzik
1 sibling, 0 replies; 3+ messages in thread
From: Stephen Hemminger @ 2007-11-28 22:50 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev
When using larger MTU's sky2 driver changes from allocating one
data area, to using multiple pages. The threshold for this was based on
a heuristic where the cost of a single allocation is bigger than one
page. Since the allocator has changed, this heuristic is now incorrect;
instead just make the threshold be when the total size of the allocation
is greater than one page.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
--- a/drivers/net/sky2.c 2007-11-28 08:46:57.000000000 -0800
+++ b/drivers/net/sky2.c 2007-11-28 14:48:26.000000000 -0800
@@ -1231,7 +1231,7 @@ static int sky2_rx_start(struct sky2_por
struct sky2_hw *hw = sky2->hw;
struct rx_ring_info *re;
unsigned rxq = rxqaddr[sky2->port];
- unsigned i, size, space, thresh;
+ unsigned i, size, thresh;
sky2->rx_put = sky2->rx_next = 0;
sky2_qset(hw, rxq);
@@ -1258,28 +1258,18 @@ static int sky2_rx_start(struct sky2_por
/* Stopping point for hardware truncation */
thresh = (size - 8) / sizeof(u32);
- /* Account for overhead of skb - to avoid order > 0 allocation */
- space = SKB_DATA_ALIGN(size) + NET_SKB_PAD
- + sizeof(struct skb_shared_info);
-
- sky2->rx_nfrags = space >> PAGE_SHIFT;
+ sky2->rx_nfrags = size >> PAGE_SHIFT;
BUG_ON(sky2->rx_nfrags > ARRAY_SIZE(re->frag_addr));
- if (sky2->rx_nfrags != 0) {
- /* Compute residue after pages */
- space = sky2->rx_nfrags << PAGE_SHIFT;
+ /* Compute residue after pages */
+ size -= sky2->rx_nfrags << PAGE_SHIFT;
- if (space < size)
- size -= space;
- else
- size = 0;
+ /* Optimize to handle small packets and headers */
+ if (size < copybreak)
+ size = copybreak;
+ if (size < ETH_HLEN)
+ size = ETH_HLEN;
- /* Optimize to handle small packets and headers */
- if (size < copybreak)
- size = copybreak;
- if (size < ETH_HLEN)
- size = ETH_HLEN;
- }
sky2->rx_data_size = size;
/* Fill Rx ring */
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH 1/2] sky2: align IP header on Rx if possible
2007-11-28 22:27 [PATCH 1/2] sky2: align IP header on Rx if possible Stephen Hemminger
2007-11-28 22:50 ` [PATCH 2/2] sky2: rx allocation threshold change Stephen Hemminger
@ 2007-12-01 21:53 ` Jeff Garzik
1 sibling, 0 replies; 3+ messages in thread
From: Jeff Garzik @ 2007-12-01 21:53 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev
Stephen Hemminger wrote:
> The sky2 driver was not aligning the IP header on receive buffers.
> This workaround is only needed on hardware with broken FIFO, newer chips
> without FIFO can just DMA to unaligned address.
>
> Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
applied 1-2
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2007-12-01 21:53 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-11-28 22:27 [PATCH 1/2] sky2: align IP header on Rx if possible Stephen Hemminger
2007-11-28 22:50 ` [PATCH 2/2] sky2: rx allocation threshold change Stephen Hemminger
2007-12-01 21:53 ` [PATCH 1/2] sky2: align IP header on Rx if possible Jeff Garzik
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).