* [PATCH 2.6.9-rc2 10/12] S2io: 2 buffer mode with copy
@ 2004-10-28 18:34 Ravinandan Arakali
0 siblings, 0 replies; 3+ messages in thread
From: Ravinandan Arakali @ 2004-10-28 18:34 UTC (permalink / raw)
To: 'Jeff Garzik', 'Francois Romieu'
Cc: netdev, leonid.grossman, raghavendra.koushik, rapuru.sriram,
alicia.pena
Hi All,
This patch addresses the comments by Chris Leech about skb->mac.ethernet
resulting in NULL dereference with the old method of implementing 2 buffer
mode. The new method performs a copy of the MAC header to the head of
the payload. This is a stop-gap measure till the fragmented skb receive
feature in the kernel is made functional.
Also, using GFP_KERNEL flag for buffer0, buffer1 memory allocation instead
of GFP_ATOMIC.
Signed-off-by: Raghavendra Koushik <raghavendra.koushik@s2io.com>
---
diff -urN vanilla-linux/drivers/net/s2io.c linux-2.6.8.1/drivers/net/s2io.c
--- vanilla-linux/drivers/net/s2io.c 2004-10-26 16:40:58.271982080 -0700
+++ linux-2.6.8.1/drivers/net/s2io.c 2004-10-26 16:40:42.944312240 -0700
@@ -497,7 +497,7 @@
ba = &nic->ba[i][j][k];
ba->ba_0_org = (void *) kmalloc
- (BUF0_LEN + ALIGN_SIZE, GFP_ATOMIC);
+ (BUF0_LEN + ALIGN_SIZE, GFP_KERNEL);
if (!ba->ba_0_org)
return -ENOMEM;
tmp = (u64) ba->ba_0_org;
@@ -506,7 +506,7 @@
ba->ba_0 = (void *) tmp;
ba->ba_1_org = (void *) kmalloc
- (BUF1_LEN + ALIGN_SIZE, GFP_ATOMIC);
+ (BUF1_LEN + ALIGN_SIZE, GFP_KERNEL);
if (!ba->ba_1_org)
return -ENOMEM;
tmp = (u64) ba->ba_1_org;
@@ -1791,8 +1791,7 @@
#ifndef CONFIG_2BUFF_MODE
skb = dev_alloc_skb(size + NET_IP_ALIGN);
#else
- skb = dev_alloc_skb(dev->mtu + ALIGN_SIZE +
- /*BUF0_LEN + */ 22);
+ skb = dev_alloc_skb(dev->mtu + ALIGN_SIZE + BUF0_LEN + 4);
#endif
if (!skb) {
DBG_PRINT(ERR_DBG, "%s: Out of ", dev->name);
@@ -1813,14 +1812,16 @@
mac_control->rx_curr_put_info[ring_no].offset = off;
#else
ba = &nic->ba[ring_no][block_no][off];
+ skb_reserve(skb, BUF0_LEN);
tmp = (u64) skb->data;
tmp += ALIGN_SIZE;
tmp &= ~ALIGN_SIZE;
skb->data = (void *) tmp;
+ skb->tail = (void *) tmp;
memset(rxdp, 0, sizeof(RxD_t));
rxdp->Buffer2_ptr = pci_map_single
- (nic->pdev, skb->data, dev->mtu + 22,
+ (nic->pdev, skb->data, dev->mtu + BUF0_LEN + 4,
PCI_DMA_FROMDEVICE);
rxdp->Buffer0_ptr =
pci_map_single(nic->pdev, ba->ba_0, BUF0_LEN,
@@ -1829,7 +1830,7 @@
pci_map_single(nic->pdev, ba->ba_1, BUF1_LEN,
PCI_DMA_FROMDEVICE);
- rxdp->Control_2 = SET_BUFFER2_SIZE(dev->mtu + 22);
+ rxdp->Control_2 = SET_BUFFER2_SIZE(dev->mtu + 4);
rxdp->Control_2 |= SET_BUFFER0_SIZE(BUF0_LEN);
rxdp->Control_2 |= SET_BUFFER1_SIZE(1); /* dummy. */
rxdp->Control_2 |= BIT(0); /* Set Buffer_Empty bit. */
@@ -1919,7 +1920,7 @@
PCI_DMA_FROMDEVICE);
pci_unmap_single(sp->pdev, (dma_addr_t)
rxdp->Buffer2_ptr,
- dev->mtu + 22,
+ dev->mtu + BUF0_LEN + 4,
PCI_DMA_FROMDEVICE);
#endif
dev_kfree_skb(skb);
@@ -2073,7 +2074,7 @@
BUF1_LEN, PCI_DMA_FROMDEVICE);
pci_unmap_single(nic->pdev, (dma_addr_t)
rxdp->Buffer2_ptr,
- dev->mtu + 22,
+ dev->mtu + BUF0_LEN + 4,
PCI_DMA_FROMDEVICE);
ba = &nic->ba[i][get_block][get_info.offset];
@@ -2270,7 +2271,7 @@
BUF1_LEN, PCI_DMA_FROMDEVICE);
pci_unmap_single(nic->pdev, (dma_addr_t)
rxdp->Buffer2_ptr,
- dev->mtu + 22,
+ dev->mtu + BUF0_LEN + 4,
PCI_DMA_FROMDEVICE);
ba = &nic->ba[i][get_block][get_info.offset];
@@ -4471,7 +4472,7 @@
u16 l3_csum, l4_csum;
#ifdef CONFIG_2BUFF_MODE
int buf0_len, buf2_len;
- struct ethhdr *eth = (struct ethhdr *) ba->ba_0;
+ unsigned char *buff;
#endif
l3_csum = RXD_GET_L3_CKSUM(rxdp->Control_1);
@@ -4510,21 +4511,10 @@
skb_put(skb, len);
skb->protocol = eth_type_trans(skb, dev);
#else
+ buff = skb_push(skb, buf0_len);
+ memcpy(buff, ba->ba_0, buf0_len);
skb_put(skb, buf2_len);
- /*
- * Reproducing eth_type_trans functionality and running
- * on the ethernet header 'eth' stripped and given to us
- * by the hardware in 2Buff mode.
- */
- if (*eth->h_dest & 1) {
- if (!memcmp(eth->h_dest, dev->broadcast, ETH_ALEN))
- skb->pkt_type = PACKET_BROADCAST;
- else
- skb->pkt_type = PACKET_MULTICAST;
- } else if (memcmp(eth->h_dest, dev->dev_addr, ETH_ALEN)) {
- skb->pkt_type = PACKET_OTHERHOST;
- }
- skb->protocol = eth->h_proto;
+ skb->protocol = eth_type_trans(skb, dev);
#endif
#ifdef CONFIG_S2IO_NAPI
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 2.6.9-rc2 10/12] S2io: 2 buffer mode with copy
@ 2004-10-28 22:51 Ravinandan Arakali
0 siblings, 0 replies; 3+ messages in thread
From: Ravinandan Arakali @ 2004-10-28 22:51 UTC (permalink / raw)
To: 'Jeff Garzik', 'Francois Romieu'
Cc: netdev, leonid.grossman, raghavendra.koushik, rapuru.sriram,
alicia.pena
Hi All,
This patch addresses the comments by Chris Leech about skb->mac.ethernet
resulting in NULL dereference with the old method of implementing 2 buffer
mode. The new method performs a copy of the MAC header to the head of
the payload. This is a stop-gap measure till the fragmented skb receive
feature in the kernel is made functional.
Also, using GFP_KERNEL flag for buffer0, buffer1 memory allocation instead
of GFP_ATOMIC.
Signed-off-by: Raghavendra Koushik <raghavendra.koushik@s2io.com>
Signed-off-by: Ravinandan Arakali <ravinandan.arakali@s2io.com>
---
diff -urN vanilla-linux/drivers/net/s2io.c linux-2.6.8.1/drivers/net/s2io.c
--- vanilla-linux/drivers/net/s2io.c 2004-10-26 16:40:58.271982080 -0700
+++ linux-2.6.8.1/drivers/net/s2io.c 2004-10-26 16:40:42.944312240 -0700
@@ -497,7 +497,7 @@
ba = &nic->ba[i][j][k];
ba->ba_0_org = (void *) kmalloc
- (BUF0_LEN + ALIGN_SIZE, GFP_ATOMIC);
+ (BUF0_LEN + ALIGN_SIZE, GFP_KERNEL);
if (!ba->ba_0_org)
return -ENOMEM;
tmp = (u64) ba->ba_0_org;
@@ -506,7 +506,7 @@
ba->ba_0 = (void *) tmp;
ba->ba_1_org = (void *) kmalloc
- (BUF1_LEN + ALIGN_SIZE, GFP_ATOMIC);
+ (BUF1_LEN + ALIGN_SIZE, GFP_KERNEL);
if (!ba->ba_1_org)
return -ENOMEM;
tmp = (u64) ba->ba_1_org;
@@ -1791,8 +1791,7 @@
#ifndef CONFIG_2BUFF_MODE
skb = dev_alloc_skb(size + NET_IP_ALIGN);
#else
- skb = dev_alloc_skb(dev->mtu + ALIGN_SIZE +
- /*BUF0_LEN + */ 22);
+ skb = dev_alloc_skb(dev->mtu + ALIGN_SIZE + BUF0_LEN + 4);
#endif
if (!skb) {
DBG_PRINT(ERR_DBG, "%s: Out of ", dev->name);
@@ -1813,14 +1812,16 @@
mac_control->rx_curr_put_info[ring_no].offset = off;
#else
ba = &nic->ba[ring_no][block_no][off];
+ skb_reserve(skb, BUF0_LEN);
tmp = (u64) skb->data;
tmp += ALIGN_SIZE;
tmp &= ~ALIGN_SIZE;
skb->data = (void *) tmp;
+ skb->tail = (void *) tmp;
memset(rxdp, 0, sizeof(RxD_t));
rxdp->Buffer2_ptr = pci_map_single
- (nic->pdev, skb->data, dev->mtu + 22,
+ (nic->pdev, skb->data, dev->mtu + BUF0_LEN + 4,
PCI_DMA_FROMDEVICE);
rxdp->Buffer0_ptr =
pci_map_single(nic->pdev, ba->ba_0, BUF0_LEN,
@@ -1829,7 +1830,7 @@
pci_map_single(nic->pdev, ba->ba_1, BUF1_LEN,
PCI_DMA_FROMDEVICE);
- rxdp->Control_2 = SET_BUFFER2_SIZE(dev->mtu + 22);
+ rxdp->Control_2 = SET_BUFFER2_SIZE(dev->mtu + 4);
rxdp->Control_2 |= SET_BUFFER0_SIZE(BUF0_LEN);
rxdp->Control_2 |= SET_BUFFER1_SIZE(1); /* dummy. */
rxdp->Control_2 |= BIT(0); /* Set Buffer_Empty bit. */
@@ -1919,7 +1920,7 @@
PCI_DMA_FROMDEVICE);
pci_unmap_single(sp->pdev, (dma_addr_t)
rxdp->Buffer2_ptr,
- dev->mtu + 22,
+ dev->mtu + BUF0_LEN + 4,
PCI_DMA_FROMDEVICE);
#endif
dev_kfree_skb(skb);
@@ -2073,7 +2074,7 @@
BUF1_LEN, PCI_DMA_FROMDEVICE);
pci_unmap_single(nic->pdev, (dma_addr_t)
rxdp->Buffer2_ptr,
- dev->mtu + 22,
+ dev->mtu + BUF0_LEN + 4,
PCI_DMA_FROMDEVICE);
ba = &nic->ba[i][get_block][get_info.offset];
@@ -2270,7 +2271,7 @@
BUF1_LEN, PCI_DMA_FROMDEVICE);
pci_unmap_single(nic->pdev, (dma_addr_t)
rxdp->Buffer2_ptr,
- dev->mtu + 22,
+ dev->mtu + BUF0_LEN + 4,
PCI_DMA_FROMDEVICE);
ba = &nic->ba[i][get_block][get_info.offset];
@@ -4471,7 +4472,7 @@
u16 l3_csum, l4_csum;
#ifdef CONFIG_2BUFF_MODE
int buf0_len, buf2_len;
- struct ethhdr *eth = (struct ethhdr *) ba->ba_0;
+ unsigned char *buff;
#endif
l3_csum = RXD_GET_L3_CKSUM(rxdp->Control_1);
@@ -4510,21 +4511,10 @@
skb_put(skb, len);
skb->protocol = eth_type_trans(skb, dev);
#else
+ buff = skb_push(skb, buf0_len);
+ memcpy(buff, ba->ba_0, buf0_len);
skb_put(skb, buf2_len);
- /*
- * Reproducing eth_type_trans functionality and running
- * on the ethernet header 'eth' stripped and given to us
- * by the hardware in 2Buff mode.
- */
- if (*eth->h_dest & 1) {
- if (!memcmp(eth->h_dest, dev->broadcast, ETH_ALEN))
- skb->pkt_type = PACKET_BROADCAST;
- else
- skb->pkt_type = PACKET_MULTICAST;
- } else if (memcmp(eth->h_dest, dev->dev_addr, ETH_ALEN)) {
- skb->pkt_type = PACKET_OTHERHOST;
- }
- skb->protocol = eth->h_proto;
+ skb->protocol = eth_type_trans(skb, dev);
#endif
#ifdef CONFIG_S2IO_NAPI
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 2.6.9-rc2 10/12] S2io: 2 buffer mode with copy
@ 2004-11-08 16:17 raghavendra.koushik
0 siblings, 0 replies; 3+ messages in thread
From: raghavendra.koushik @ 2004-11-08 16:17 UTC (permalink / raw)
To: jgarzik, romieu, netdev; +Cc: ravinandan.arakali, raghavendra.koushik
Hi All,
This patch addresses the comments by Chris Leech about skb->mac.ethernet
resulting in NULL dereference with the old method of implementing 2 buffer
mode. The new method performs a copy of the MAC header to the head of
the payload. This is a stop-gap measure till the fragmented skb receive
feature in the kernel is made functional.
Also, using GFP_KERNEL flag for buffer0, buffer1 memory allocation instead
of GFP_ATOMIC.
Signed-off-by: Raghavendra Koushik <raghavendra.koushik@s2io.com>
Signed-off-by: Ravinandan Arakali <ravinandan.arakali@s2io.com>
---
diff -urN vanilla-linux/drivers/net/s2io.c linux-2.6.8.1/drivers/net/s2io.c
--- vanilla-linux/drivers/net/s2io.c 2004-10-26 16:40:58.271982080 -0700
+++ linux-2.6.8.1/drivers/net/s2io.c 2004-10-26 16:40:42.944312240 -0700
@@ -497,7 +497,7 @@
ba = &nic->ba[i][j][k];
ba->ba_0_org = (void *) kmalloc
- (BUF0_LEN + ALIGN_SIZE, GFP_ATOMIC);
+ (BUF0_LEN + ALIGN_SIZE, GFP_KERNEL);
if (!ba->ba_0_org)
return -ENOMEM;
tmp = (u64) ba->ba_0_org;
@@ -506,7 +506,7 @@
ba->ba_0 = (void *) tmp;
ba->ba_1_org = (void *) kmalloc
- (BUF1_LEN + ALIGN_SIZE, GFP_ATOMIC);
+ (BUF1_LEN + ALIGN_SIZE, GFP_KERNEL);
if (!ba->ba_1_org)
return -ENOMEM;
tmp = (u64) ba->ba_1_org;
@@ -1791,8 +1791,7 @@
#ifndef CONFIG_2BUFF_MODE
skb = dev_alloc_skb(size + NET_IP_ALIGN);
#else
- skb = dev_alloc_skb(dev->mtu + ALIGN_SIZE +
- /*BUF0_LEN + */ 22);
+ skb = dev_alloc_skb(dev->mtu + ALIGN_SIZE + BUF0_LEN + 4);
#endif
if (!skb) {
DBG_PRINT(ERR_DBG, "%s: Out of ", dev->name);
@@ -1813,14 +1812,16 @@
mac_control->rx_curr_put_info[ring_no].offset = off;
#else
ba = &nic->ba[ring_no][block_no][off];
+ skb_reserve(skb, BUF0_LEN);
tmp = (u64) skb->data;
tmp += ALIGN_SIZE;
tmp &= ~ALIGN_SIZE;
skb->data = (void *) tmp;
+ skb->tail = (void *) tmp;
memset(rxdp, 0, sizeof(RxD_t));
rxdp->Buffer2_ptr = pci_map_single
- (nic->pdev, skb->data, dev->mtu + 22,
+ (nic->pdev, skb->data, dev->mtu + BUF0_LEN + 4,
PCI_DMA_FROMDEVICE);
rxdp->Buffer0_ptr =
pci_map_single(nic->pdev, ba->ba_0, BUF0_LEN,
@@ -1829,7 +1830,7 @@
pci_map_single(nic->pdev, ba->ba_1, BUF1_LEN,
PCI_DMA_FROMDEVICE);
- rxdp->Control_2 = SET_BUFFER2_SIZE(dev->mtu + 22);
+ rxdp->Control_2 = SET_BUFFER2_SIZE(dev->mtu + 4);
rxdp->Control_2 |= SET_BUFFER0_SIZE(BUF0_LEN);
rxdp->Control_2 |= SET_BUFFER1_SIZE(1); /* dummy. */
rxdp->Control_2 |= BIT(0); /* Set Buffer_Empty bit. */
@@ -1919,7 +1920,7 @@
PCI_DMA_FROMDEVICE);
pci_unmap_single(sp->pdev, (dma_addr_t)
rxdp->Buffer2_ptr,
- dev->mtu + 22,
+ dev->mtu + BUF0_LEN + 4,
PCI_DMA_FROMDEVICE);
#endif
dev_kfree_skb(skb);
@@ -2073,7 +2074,7 @@
BUF1_LEN, PCI_DMA_FROMDEVICE);
pci_unmap_single(nic->pdev, (dma_addr_t)
rxdp->Buffer2_ptr,
- dev->mtu + 22,
+ dev->mtu + BUF0_LEN + 4,
PCI_DMA_FROMDEVICE);
ba = &nic->ba[i][get_block][get_info.offset];
@@ -2270,7 +2271,7 @@
BUF1_LEN, PCI_DMA_FROMDEVICE);
pci_unmap_single(nic->pdev, (dma_addr_t)
rxdp->Buffer2_ptr,
- dev->mtu + 22,
+ dev->mtu + BUF0_LEN + 4,
PCI_DMA_FROMDEVICE);
ba = &nic->ba[i][get_block][get_info.offset];
@@ -4471,7 +4472,7 @@
u16 l3_csum, l4_csum;
#ifdef CONFIG_2BUFF_MODE
int buf0_len, buf2_len;
- struct ethhdr *eth = (struct ethhdr *) ba->ba_0;
+ unsigned char *buff;
#endif
l3_csum = RXD_GET_L3_CKSUM(rxdp->Control_1);
@@ -4510,21 +4511,10 @@
skb_put(skb, len);
skb->protocol = eth_type_trans(skb, dev);
#else
+ buff = skb_push(skb, buf0_len);
+ memcpy(buff, ba->ba_0, buf0_len);
skb_put(skb, buf2_len);
- /*
- * Reproducing eth_type_trans functionality and running
- * on the ethernet header 'eth' stripped and given to us
- * by the hardware in 2Buff mode.
- */
- if (*eth->h_dest & 1) {
- if (!memcmp(eth->h_dest, dev->broadcast, ETH_ALEN))
- skb->pkt_type = PACKET_BROADCAST;
- else
- skb->pkt_type = PACKET_MULTICAST;
- } else if (memcmp(eth->h_dest, dev->dev_addr, ETH_ALEN)) {
- skb->pkt_type = PACKET_OTHERHOST;
- }
- skb->protocol = eth->h_proto;
+ skb->protocol = eth_type_trans(skb, dev);
#endif
#ifdef CONFIG_S2IO_NAPI
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2004-11-08 16:17 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-11-08 16:17 [PATCH 2.6.9-rc2 10/12] S2io: 2 buffer mode with copy raghavendra.koushik
-- strict thread matches above, loose matches on Subject: below --
2004-10-28 22:51 Ravinandan Arakali
2004-10-28 18:34 Ravinandan Arakali
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).