* [PATCH v2 12/46] net: sunhme: cleanup RX skb allocation
From: Michał Mirosław @ 2011-07-11 0:52 UTC (permalink / raw)
To: netdev
In-Reply-To: <cover.1310339688.git.mirq-linux@rere.qmqm.pl>
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
drivers/net/sunhme.c | 18 ++++++++----------
drivers/net/sunhme.h | 14 +-------------
2 files changed, 9 insertions(+), 23 deletions(-)
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index 856e05b..c73fdad 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -1265,7 +1265,8 @@ static void happy_meal_init_rings(struct happy_meal *hp)
for (i = 0; i < RX_RING_SIZE; i++) {
struct sk_buff *skb;
- skb = happy_meal_alloc_skb(RX_BUF_ALLOC_SIZE, GFP_ATOMIC);
+ skb = __netdev_alloc_skb_aligned(dev, RX_BUF_ALLOC_SIZE,
+ SUNHME_RX_ALIGNMENT, GFP_ATOMIC);
if (!skb) {
hme_write_rxd(hp, &hb->happy_meal_rxd[i], 0, 0);
continue;
@@ -1273,8 +1274,6 @@ static void happy_meal_init_rings(struct happy_meal *hp)
hp->rx_skbs[i] = skb;
skb->dev = dev;
- /* Because we reserve afterwards. */
- skb_put(skb, (ETH_FRAME_LEN + RX_OFFSET + 4));
hme_write_rxd(hp, &hb->happy_meal_rxd[i],
(RXFLAG_OWN | ((RX_BUF_ALLOC_SIZE - RX_OFFSET) << 16)),
dma_map_single(hp->dma_dev, skb->data, RX_BUF_ALLOC_SIZE,
@@ -2025,32 +2024,31 @@ static void happy_meal_rx(struct happy_meal *hp, struct net_device *dev)
struct sk_buff *new_skb;
/* Now refill the entry, if we can. */
- new_skb = happy_meal_alloc_skb(RX_BUF_ALLOC_SIZE, GFP_ATOMIC);
+ new_skb = __netdev_alloc_skb_aligned(dev,
+ RX_BUF_ALLOC_SIZE,
+ SUNHME_RX_ALIGNMENT,
+ GFP_ATOMIC);
if (new_skb == NULL) {
drops++;
goto drop_it;
}
dma_unmap_single(hp->dma_dev, dma_addr, RX_BUF_ALLOC_SIZE, DMA_FROM_DEVICE);
hp->rx_skbs[elem] = new_skb;
- new_skb->dev = dev;
- skb_put(new_skb, (ETH_FRAME_LEN + RX_OFFSET + 4));
hme_write_rxd(hp, this,
(RXFLAG_OWN|((RX_BUF_ALLOC_SIZE-RX_OFFSET)<<16)),
dma_map_single(hp->dma_dev, new_skb->data, RX_BUF_ALLOC_SIZE,
DMA_FROM_DEVICE));
skb_reserve(new_skb, RX_OFFSET);
- /* Trim the original skb for the netif. */
- skb_trim(skb, len);
+ skb_put(skb, len);
} else {
- struct sk_buff *copy_skb = dev_alloc_skb(len + 2);
+ struct sk_buff *copy_skb = netdev_alloc_skb_ip_align(dev, len);
if (copy_skb == NULL) {
drops++;
goto drop_it;
}
- skb_reserve(copy_skb, 2);
skb_put(copy_skb, len);
dma_sync_single_for_cpu(hp->dma_dev, dma_addr, len, DMA_FROM_DEVICE);
skb_copy_from_linear_data(skb, copy_skb->data, len);
diff --git a/drivers/net/sunhme.h b/drivers/net/sunhme.h
index 64f2783..f584eb0 100644
--- a/drivers/net/sunhme.h
+++ b/drivers/net/sunhme.h
@@ -495,18 +495,6 @@ struct quattro {
int nranges;
};
-/* We use this to acquire receive skb's that we can DMA directly into. */
-#define ALIGNED_RX_SKB_ADDR(addr) \
- ((((unsigned long)(addr) + (64UL - 1UL)) & ~(64UL - 1UL)) - (unsigned long)(addr))
-#define happy_meal_alloc_skb(__length, __gfp_flags) \
-({ struct sk_buff *__skb; \
- __skb = alloc_skb((__length) + 64, (__gfp_flags)); \
- if(__skb) { \
- int __offset = (int) ALIGNED_RX_SKB_ADDR(__skb->data); \
- if(__offset) \
- skb_reserve(__skb, __offset); \
- } \
- __skb; \
-})
+#define SUNHME_RX_ALIGNMENT 64
#endif /* !(_SUNHME_H) */
--
1.7.5.4
^ permalink raw reply related
* [PATCH v2 11/46] net: sungem: cleanup RX skb allocation
From: Michał Mirosław @ 2011-07-11 0:52 UTC (permalink / raw)
To: netdev
In-Reply-To: <cover.1310339688.git.mirq-linux@rere.qmqm.pl>
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
drivers/net/sungem.c | 34 +++++++++++-----------------------
drivers/net/sungem.h | 4 +++-
2 files changed, 14 insertions(+), 24 deletions(-)
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index ade35dd..e82617f 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -743,21 +743,6 @@ static __inline__ void gem_post_rxds(struct gem *gp, int limit)
}
}
-#define ALIGNED_RX_SKB_ADDR(addr) \
- ((((unsigned long)(addr) + (64UL - 1UL)) & ~(64UL - 1UL)) - (unsigned long)(addr))
-static __inline__ struct sk_buff *gem_alloc_skb(struct net_device *dev, int size,
- gfp_t gfp_flags)
-{
- struct sk_buff *skb = alloc_skb(size + 64, gfp_flags);
-
- if (likely(skb)) {
- unsigned long offset = ALIGNED_RX_SKB_ADDR(skb->data);
- skb_reserve(skb, offset);
- skb->dev = dev;
- }
- return skb;
-}
-
static int gem_rx(struct gem *gp, int work_to_do)
{
struct net_device *dev = gp->dev;
@@ -821,7 +806,10 @@ static int gem_rx(struct gem *gp, int work_to_do)
if (len > RX_COPY_THRESHOLD) {
struct sk_buff *new_skb;
- new_skb = gem_alloc_skb(dev, RX_BUF_ALLOC_SIZE(gp), GFP_ATOMIC);
+ new_skb = __netdev_alloc_skb_aligned(dev,
+ RX_BUF_ALLOC_SIZE(gp),
+ SUNGEM_RX_ALIGNMENT,
+ GFP_ATOMIC);
if (new_skb == NULL) {
drops++;
goto drop_it;
@@ -830,7 +818,6 @@ static int gem_rx(struct gem *gp, int work_to_do)
RX_BUF_ALLOC_SIZE(gp),
PCI_DMA_FROMDEVICE);
gp->rx_skbs[entry] = new_skb;
- skb_put(new_skb, (gp->rx_buf_sz + RX_OFFSET));
rxd->buffer = cpu_to_le64(pci_map_page(gp->pdev,
virt_to_page(new_skb->data),
offset_in_page(new_skb->data),
@@ -838,17 +825,16 @@ static int gem_rx(struct gem *gp, int work_to_do)
PCI_DMA_FROMDEVICE));
skb_reserve(new_skb, RX_OFFSET);
- /* Trim the original skb for the netif. */
- skb_trim(skb, len);
+ skb_put(skb, len);
} else {
- struct sk_buff *copy_skb = netdev_alloc_skb(dev, len + 2);
+ struct sk_buff *copy_skb =
+ netdev_alloc_skb_ip_align(dev, len);
if (copy_skb == NULL) {
drops++;
goto drop_it;
}
- skb_reserve(copy_skb, 2);
skb_put(copy_skb, len);
pci_dma_sync_single_for_cpu(gp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE);
skb_copy_from_linear_data(skb, copy_skb->data, len);
@@ -1637,7 +1623,10 @@ static void gem_init_rings(struct gem *gp)
struct sk_buff *skb;
struct gem_rxd *rxd = &gb->rxd[i];
- skb = gem_alloc_skb(dev, RX_BUF_ALLOC_SIZE(gp), GFP_KERNEL);
+ skb = __netdev_alloc_skb_aligned(dev,
+ RX_BUF_ALLOC_SIZE(gp),
+ SUNGEM_RX_ALIGNMENT,
+ GFP_KERNEL);
if (!skb) {
rxd->buffer = 0;
rxd->status_word = 0;
@@ -1645,7 +1634,6 @@ static void gem_init_rings(struct gem *gp)
}
gp->rx_skbs[i] = skb;
- skb_put(skb, (gp->rx_buf_sz + RX_OFFSET));
dma_addr = pci_map_page(gp->pdev,
virt_to_page(skb->data),
offset_in_page(skb->data),
diff --git a/drivers/net/sungem.h b/drivers/net/sungem.h
index 835ce1b..0d486ce 100644
--- a/drivers/net/sungem.h
+++ b/drivers/net/sungem.h
@@ -935,7 +935,9 @@ struct gem_rxd {
(GP)->tx_old - (GP)->tx_new - 1)
#define RX_OFFSET 2
-#define RX_BUF_ALLOC_SIZE(gp) ((gp)->rx_buf_sz + 28 + RX_OFFSET + 64)
+#define SUNGEM_RX_ALIGNMENT 64 /* min: cache line size, see comment above */
+#define RX_BUF_ALLOC_SIZE(gp) \
+ ALIGN((gp)->rx_buf_sz + RX_OFFSET, SUNGEM_RX_ALIGNMENT)
#define RX_COPY_THRESHOLD 256
--
1.7.5.4
^ permalink raw reply related
* [PATCH v2 14/46] net: sunbmac: cleanup magic '34'
From: Michał Mirosław @ 2011-07-11 0:52 UTC (permalink / raw)
To: netdev
In-Reply-To: <cover.1310339688.git.mirq-linux@rere.qmqm.pl>
Offset of 34 bytes (32+2) after aligning the skb->data to 64 looks
suspicious. Remove the alignment, and use NET_IP_ALIGN instead of the magic.
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
drivers/net/sunbmac.c | 32 ++++++++++++++------------------
1 files changed, 14 insertions(+), 18 deletions(-)
diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c
index e28d3ea..efc5389 100644
--- a/drivers/net/sunbmac.c
+++ b/drivers/net/sunbmac.c
@@ -228,24 +228,21 @@ static void bigmac_init_rings(struct bigmac *bp, int from_irq)
for (i = 0; i < RX_RING_SIZE; i++) {
struct sk_buff *skb;
- skb = __netdev_alloc_skb_aligned(dev,
- RX_BUF_ALLOC_SIZE,
- SUNBMAC_RX_ALIGNMENT,
- gfp_flags);
+ skb = __netdev_alloc_skb(dev, RX_BUF_ALLOC_SIZE,
+ gfp_flags);
if (!skb)
continue;
bp->rx_skbs[i] = skb;
-
- skb_reserve(skb, 34);
+ skb_reserve(skb, NET_IP_ALIGN);
bb->be_rxd[i].rx_addr =
dma_map_single(&bp->bigmac_op->dev,
skb->data,
- RX_BUF_ALLOC_SIZE - 34,
+ RX_BUF_ALLOC_SIZE - NET_IP_ALIGN,
DMA_FROM_DEVICE);
bb->be_rxd[i].rx_flags =
- (RXD_OWN | ((RX_BUF_ALLOC_SIZE - 34) & RXD_LENGTH));
+ (RXD_OWN | ((RX_BUF_ALLOC_SIZE - NET_IP_ALIGN) & RXD_LENGTH));
}
for (i = 0; i < TX_RING_SIZE; i++)
@@ -820,7 +817,7 @@ static void bigmac_rx(struct bigmac *bp)
/* Return it to the BigMAC. */
bp->enet_stats.rx_dropped++;
this->rx_flags =
- (RXD_OWN | ((RX_BUF_ALLOC_SIZE - 34) & RXD_LENGTH));
+ (RXD_OWN | ((RX_BUF_ALLOC_SIZE - NET_IP_ALIGN) & RXD_LENGTH));
goto next;
}
skb = bp->rx_skbs[elem];
@@ -828,27 +825,26 @@ static void bigmac_rx(struct bigmac *bp)
struct sk_buff *new_skb;
/* Now refill the entry, if we can. */
- new_skb = __netdev_alloc_skb_aligned(dev,
- RX_BUF_ALLOC_SIZE,
- SUNBMAC_RX_ALIGNMENT,
- GFP_ATOMIC);
+ new_skb = __netdev_alloc_skb(dev,
+ RX_BUF_ALLOC_SIZE,
+ GFP_ATOMIC);
if (new_skb == NULL) {
drops++;
goto drop_it;
}
dma_unmap_single(&bp->bigmac_op->dev,
this->rx_addr,
- RX_BUF_ALLOC_SIZE - 34,
+ RX_BUF_ALLOC_SIZE - NET_IP_ALIGN,
DMA_FROM_DEVICE);
bp->rx_skbs[elem] = new_skb;
- skb_reserve(new_skb, 34);
+ skb_reserve(new_skb, NET_IP_ALIGN);
this->rx_addr =
dma_map_single(&bp->bigmac_op->dev,
new_skb->data,
- RX_BUF_ALLOC_SIZE - 34,
+ RX_BUF_ALLOC_SIZE - NET_IP_ALIGN,
DMA_FROM_DEVICE);
this->rx_flags =
- (RXD_OWN | ((RX_BUF_ALLOC_SIZE - 34) & RXD_LENGTH));
+ (RXD_OWN | ((RX_BUF_ALLOC_SIZE - NET_IP_ALIGN) & RXD_LENGTH));
skb_put(skb, len);
} else {
@@ -870,7 +866,7 @@ static void bigmac_rx(struct bigmac *bp)
/* Reuse original ring buffer. */
this->rx_flags =
- (RXD_OWN | ((RX_BUF_ALLOC_SIZE - 34) & RXD_LENGTH));
+ (RXD_OWN | ((RX_BUF_ALLOC_SIZE - NET_IP_ALIGN) & RXD_LENGTH));
skb = copy_skb;
}
--
1.7.5.4
^ permalink raw reply related
* [PATCH v2 13/46] net: sunbmac: cleanup RX skb allocation
From: Michał Mirosław @ 2011-07-11 0:52 UTC (permalink / raw)
To: netdev
In-Reply-To: <cover.1310339688.git.mirq-linux@rere.qmqm.pl>
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
drivers/net/sunbmac.c | 22 +++++++++++-----------
drivers/net/sunbmac.h | 18 +-----------------
2 files changed, 12 insertions(+), 28 deletions(-)
diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c
index 297a424..e28d3ea 100644
--- a/drivers/net/sunbmac.c
+++ b/drivers/net/sunbmac.c
@@ -228,15 +228,15 @@ static void bigmac_init_rings(struct bigmac *bp, int from_irq)
for (i = 0; i < RX_RING_SIZE; i++) {
struct sk_buff *skb;
- skb = big_mac_alloc_skb(RX_BUF_ALLOC_SIZE, gfp_flags);
+ skb = __netdev_alloc_skb_aligned(dev,
+ RX_BUF_ALLOC_SIZE,
+ SUNBMAC_RX_ALIGNMENT,
+ gfp_flags);
if (!skb)
continue;
bp->rx_skbs[i] = skb;
- skb->dev = dev;
- /* Because we reserve afterwards. */
- skb_put(skb, ETH_FRAME_LEN);
skb_reserve(skb, 34);
bb->be_rxd[i].rx_addr =
@@ -828,7 +828,10 @@ static void bigmac_rx(struct bigmac *bp)
struct sk_buff *new_skb;
/* Now refill the entry, if we can. */
- new_skb = big_mac_alloc_skb(RX_BUF_ALLOC_SIZE, GFP_ATOMIC);
+ new_skb = __netdev_alloc_skb_aligned(dev,
+ RX_BUF_ALLOC_SIZE,
+ SUNBMAC_RX_ALIGNMENT,
+ GFP_ATOMIC);
if (new_skb == NULL) {
drops++;
goto drop_it;
@@ -838,8 +841,6 @@ static void bigmac_rx(struct bigmac *bp)
RX_BUF_ALLOC_SIZE - 34,
DMA_FROM_DEVICE);
bp->rx_skbs[elem] = new_skb;
- new_skb->dev = bp->dev;
- skb_put(new_skb, ETH_FRAME_LEN);
skb_reserve(new_skb, 34);
this->rx_addr =
dma_map_single(&bp->bigmac_op->dev,
@@ -849,16 +850,15 @@ static void bigmac_rx(struct bigmac *bp)
this->rx_flags =
(RXD_OWN | ((RX_BUF_ALLOC_SIZE - 34) & RXD_LENGTH));
- /* Trim the original skb for the netif. */
- skb_trim(skb, len);
+ skb_put(skb, len);
} else {
- struct sk_buff *copy_skb = dev_alloc_skb(len + 2);
+ struct sk_buff *copy_skb =
+ netdev_alloc_skb_ip_align(dev, len);
if (copy_skb == NULL) {
drops++;
goto drop_it;
}
- skb_reserve(copy_skb, 2);
skb_put(copy_skb, len);
dma_sync_single_for_cpu(&bp->bigmac_op->dev,
this->rx_addr, len,
diff --git a/drivers/net/sunbmac.h b/drivers/net/sunbmac.h
index 4943e97..63dab2f 100644
--- a/drivers/net/sunbmac.h
+++ b/drivers/net/sunbmac.h
@@ -334,22 +334,6 @@ struct bigmac {
struct net_device *dev;
};
-/* We use this to acquire receive skb's that we can DMA directly into. */
-#define ALIGNED_RX_SKB_ADDR(addr) \
- ((((unsigned long)(addr) + (64 - 1)) & ~(64 - 1)) - (unsigned long)(addr))
-
-static inline struct sk_buff *big_mac_alloc_skb(unsigned int length, gfp_t gfp_flags)
-{
- struct sk_buff *skb;
-
- skb = alloc_skb(length + 64, gfp_flags);
- if(skb) {
- int offset = ALIGNED_RX_SKB_ADDR(skb->data);
-
- if(offset)
- skb_reserve(skb, offset);
- }
- return skb;
-}
+#define SUNBMAC_RX_ALIGNMENT 64
#endif /* !(_SUNBMAC_H) */
--
1.7.5.4
^ permalink raw reply related
* [PATCH v2 16/46] net: cxgb3: don't drop packets on memory pressure in driver
From: Michał Mirosław @ 2011-07-11 0:52 UTC (permalink / raw)
To: netdev; +Cc: Divy Le Ray
In-Reply-To: <cover.1310339688.git.mirq-linux@rere.qmqm.pl>
Dropping received packets should be left to upper layers.
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
drivers/net/cxgb3/sge.c | 8 ++------
1 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index 3196fdd..d322d3e 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -66,7 +66,6 @@
#define FL1_PG_ORDER (PAGE_SIZE > 8192 ? 0 : 1)
#define FL1_PG_ALLOC_SIZE (PAGE_SIZE << FL1_PG_ORDER)
-#define SGE_RX_DROP_THRES 16
#define RX_RECLAIM_PERIOD (HZ/4)
/*
@@ -2338,13 +2337,10 @@ no_mem:
}
skb = get_packet_pg(adap, fl, q,
- G_RSPD_LEN(len),
- eth ?
- SGE_RX_DROP_THRES : 0);
+ G_RSPD_LEN(len), 0);
q->pg_skb = skb;
} else
- skb = get_packet(adap, fl, G_RSPD_LEN(len),
- eth ? SGE_RX_DROP_THRES : 0);
+ skb = get_packet(adap, fl, G_RSPD_LEN(len), 0);
if (unlikely(!skb)) {
if (!eth)
goto no_mem;
--
1.7.5.4
^ permalink raw reply related
* [PATCH v2 09/46] net: octeon_mgmt: fix DMA unmap size
From: Michał Mirosław @ 2011-07-11 0:52 UTC (permalink / raw)
To: netdev
In-Reply-To: <cover.1310339688.git.mirq-linux@rere.qmqm.pl>
Also: use netdev_alloc_skb_ip_align() for readability.
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
drivers/net/octeon/octeon_mgmt.c | 9 ++++-----
1 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/net/octeon/octeon_mgmt.c b/drivers/net/octeon/octeon_mgmt.c
index 429e08c..dd4a57a 100644
--- a/drivers/net/octeon/octeon_mgmt.c
+++ b/drivers/net/octeon/octeon_mgmt.c
@@ -152,16 +152,15 @@ static void octeon_mgmt_rx_fill_ring(struct net_device *netdev)
struct sk_buff *skb;
/* CN56XX pass 1 needs 8 bytes of padding. */
- size = netdev->mtu + OCTEON_MGMT_RX_HEADROOM + 8 + NET_IP_ALIGN;
+ size = netdev->mtu + OCTEON_MGMT_RX_HEADROOM + 8;
- skb = netdev_alloc_skb(netdev, size);
+ skb = netdev_alloc_skb_ip_align(netdev, size);
if (!skb)
break;
- skb_reserve(skb, NET_IP_ALIGN);
__skb_queue_tail(&p->rx_list, skb);
re.d64 = 0;
- re.s.len = size;
+ re.s.len = size = skb_tailroom(skb);
re.s.addr = dma_map_single(p->dev, skb->data,
size,
DMA_FROM_DEVICE);
@@ -297,7 +296,7 @@ static u64 octeon_mgmt_dequeue_rx_buffer(struct octeon_mgmt *p,
*pskb = __skb_dequeue(&p->rx_list);
dma_unmap_single(p->dev, re.s.addr,
- ETH_FRAME_LEN + OCTEON_MGMT_RX_HEADROOM,
+ skb_tailroom(*pskb),
DMA_FROM_DEVICE);
return re.d64;
--
1.7.5.4
^ permalink raw reply related
* [PATCH v2 10/46] net: jme: convert to generic DMA API
From: Michał Mirosław @ 2011-07-11 0:52 UTC (permalink / raw)
To: netdev; +Cc: Guo-Fu Tseng
In-Reply-To: <cover.1310339688.git.mirq-linux@rere.qmqm.pl>
This also fixes bad pci_dma_map_page() usage and missing RX unmaps.
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
drivers/net/jme.c | 37 ++++++++++++-------------------------
1 files changed, 12 insertions(+), 25 deletions(-)
diff --git a/drivers/net/jme.c b/drivers/net/jme.c
index 6b2a5e7..ad69dae 100644
--- a/drivers/net/jme.c
+++ b/drivers/net/jme.c
@@ -759,11 +759,8 @@ jme_make_new_rx_buf(struct jme_adapter *jme, int i)
rxbi->skb = skb;
rxbi->len = skb_tailroom(skb);
- rxbi->mapping = pci_map_page(jme->pdev,
- virt_to_page(skb->data),
- offset_in_page(skb->data),
- rxbi->len,
- PCI_DMA_FROMDEVICE);
+ rxbi->mapping = dma_map_single(&jme->pdev->dev, skb->data,
+ rxbi->len, DMA_FROM_DEVICE);
return 0;
}
@@ -776,10 +773,10 @@ jme_free_rx_buf(struct jme_adapter *jme, int i)
rxbi += i;
if (rxbi->skb) {
- pci_unmap_page(jme->pdev,
+ dma_unmap_single(&jme->pdev->dev,
rxbi->mapping,
rxbi->len,
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
dev_kfree_skb(rxbi->skb);
rxbi->skb = NULL;
rxbi->mapping = 0;
@@ -1022,17 +1019,12 @@ jme_alloc_and_feed_skb(struct jme_adapter *jme, int idx)
rxbi += idx;
skb = rxbi->skb;
- pci_dma_sync_single_for_cpu(jme->pdev,
- rxbi->mapping,
- rxbi->len,
- PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&jme->pdev->dev, rxbi->mapping, rxbi->len,
+ DMA_FROM_DEVICE);
if (unlikely(jme_make_new_rx_buf(jme, idx))) {
- pci_dma_sync_single_for_device(jme->pdev,
- rxbi->mapping,
- rxbi->len,
- PCI_DMA_FROMDEVICE);
-
+ rxbi->mapping = dma_map_single(&jme->pdev->dev, skb->data,
+ rxbi->len, DMA_FROM_DEVICE);
++(NET_STAT(jme).rx_dropped);
} else {
framesize = le16_to_cpu(rxdesc->descwb.framesize)
@@ -1476,10 +1468,10 @@ jme_tx_clean_tasklet(unsigned long arg)
ttxbi = txbi + ((i + j) & (mask));
txdesc[(i + j) & (mask)].dw[0] = 0;
- pci_unmap_page(jme->pdev,
+ dma_unmap_page(&jme->pdev->dev,
ttxbi->mapping,
ttxbi->len,
- PCI_DMA_TODEVICE);
+ DMA_TO_DEVICE);
ttxbi->mapping = 0;
ttxbi->len = 0;
@@ -1883,16 +1875,11 @@ jme_fill_tx_map(struct pci_dev *pdev,
{
dma_addr_t dmaaddr;
- dmaaddr = pci_map_page(pdev,
+ dmaaddr = dma_map_page(&pdev->dev,
page,
page_offset,
len,
- PCI_DMA_TODEVICE);
-
- pci_dma_sync_single_for_device(pdev,
- dmaaddr,
- len,
- PCI_DMA_TODEVICE);
+ DMA_TO_DEVICE);
txdesc->dw[0] = 0;
txdesc->dw[1] = 0;
--
1.7.5.4
^ permalink raw reply related
* [PATCH v2 05/46] net: bnx2x: fix DMA sync direction
From: Michał Mirosław @ 2011-07-11 0:52 UTC (permalink / raw)
To: netdev; +Cc: Eilon Greenstein
In-Reply-To: <cover.1310339688.git.mirq-linux@rere.qmqm.pl>
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
drivers/net/bnx2x/bnx2x_cmn.c | 2 +-
drivers/net/bnx2x/bnx2x_ethtool.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c
index bb75560..4f9164c 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/bnx2x/bnx2x_cmn.c
@@ -658,7 +658,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
/* non TPA */
len = le16_to_cpu(cqe_fp->pkt_len);
pad = cqe_fp->placement_offset;
- dma_sync_single_for_device(&bp->pdev->dev,
+ dma_sync_single_for_cpu(&bp->pdev->dev,
dma_unmap_addr(rx_buf, mapping),
pad + RX_COPY_THRESH,
DMA_FROM_DEVICE);
diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c
index 1a3ed41..9a98b83 100644
--- a/drivers/net/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/bnx2x/bnx2x_ethtool.c
@@ -1751,7 +1751,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode)
goto test_loopback_rx_exit;
rx_buf = &fp_rx->rx_buf_ring[RX_BD(fp_rx->rx_bd_cons)];
- dma_sync_single_for_device(&bp->pdev->dev,
+ dma_sync_single_for_cpu(&bp->pdev->dev,
dma_unmap_addr(rx_buf, mapping),
fp_rx->rx_buf_size, DMA_FROM_DEVICE);
skb = rx_buf->skb;
--
1.7.5.4
^ permalink raw reply related
* [PATCH v2 06/46] net/tokenring: 3c359: fix DMA API usage
From: Michał Mirosław @ 2011-07-11 0:52 UTC (permalink / raw)
To: netdev
In-Reply-To: <cover.1310339688.git.mirq-linux@rere.qmqm.pl>
TX/RX rings should be allocated from DMA coherent memory (driver does
not sync the descriptors in any way).
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
drivers/net/tokenring/3c359.c | 49 +++++++++++++++++++++++++----------------
drivers/net/tokenring/3c359.h | 4 +-
2 files changed, 32 insertions(+), 21 deletions(-)
diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c
index b6162fe..d321640 100644
--- a/drivers/net/tokenring/3c359.c
+++ b/drivers/net/tokenring/3c359.c
@@ -672,21 +672,25 @@ static int xl_open(struct net_device *dev)
* Now to set up the Rx and Tx buffer structures
*/
/* These MUST be on 8 byte boundaries */
- xl_priv->xl_tx_ring = kzalloc((sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE) + 7, GFP_DMA | GFP_KERNEL);
+ xl_priv->xl_tx_ring = dma_alloc_coherent(&xl_priv->pdev->dev,
+ sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE,
+ &xl_priv->tx_ring_dma_addr, GFP_KERNEL);
if (xl_priv->xl_tx_ring == NULL) {
printk(KERN_WARNING "%s: Not enough memory to allocate tx buffers.\n",
dev->name);
- free_irq(dev->irq,dev);
- return -ENOMEM;
+ goto err_free_irq;
}
- xl_priv->xl_rx_ring = kzalloc((sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE) +7, GFP_DMA | GFP_KERNEL);
+ xl_priv->xl_rx_ring = dma_alloc_coherent(&xl_priv->pdev->dev,
+ sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE,
+ &xl_priv->rx_ring_dma_addr, GFP_KERNEL);
if (xl_priv->xl_rx_ring == NULL) {
printk(KERN_WARNING "%s: Not enough memory to allocate rx buffers.\n",
dev->name);
- free_irq(dev->irq,dev);
- kfree(xl_priv->xl_tx_ring);
- return -ENOMEM;
+ goto err_free_tx;
}
+ /* dma_alloc_coherent() should provide for the following */
+ BUG_ON(!IS_ALIGNED((unsigned long)xl_priv->xl_tx_ring, 8));
+ BUG_ON(!IS_ALIGNED((unsigned long)xl_priv->xl_rx_ring, 8));
/* Setup Rx Ring */
for (i=0 ; i < XL_RX_RING_SIZE ; i++) {
@@ -704,10 +708,7 @@ static int xl_open(struct net_device *dev)
if (i==0) {
printk(KERN_WARNING "%s: Not enough memory to allocate rx buffers. Adapter disabled\n",dev->name);
- free_irq(dev->irq,dev) ;
- kfree(xl_priv->xl_tx_ring);
- kfree(xl_priv->xl_rx_ring);
- return -EIO ;
+ goto err_free_rxtx;
}
xl_priv->rx_ring_no = i ;
@@ -722,8 +723,6 @@ static int xl_open(struct net_device *dev)
/* Setup Tx Ring */
- xl_priv->tx_ring_dma_addr = pci_map_single(xl_priv->pdev,xl_priv->xl_tx_ring, sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE,PCI_DMA_TODEVICE) ;
-
xl_priv->tx_ring_head = 1 ;
xl_priv->tx_ring_tail = 255 ; /* Special marker for first packet */
xl_priv->free_ring_entries = XL_TX_RING_SIZE ;
@@ -752,7 +751,18 @@ static int xl_open(struct net_device *dev)
netif_start_queue(dev) ;
return 0;
-
+
+err_free_rxtx:
+ dma_free_coherent(&xl_priv->pdev->dev,
+ sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE,
+ xl_priv->xl_rx_ring, xl_priv->rx_ring_dma_addr);
+err_free_tx:
+ dma_free_coherent(&xl_priv->pdev->dev,
+ sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE,
+ xl_priv->xl_tx_ring, xl_priv->tx_ring_dma_addr);
+err_free_irq:
+ free_irq(dev->irq,dev);
+ return -ENOMEM;
}
static int xl_open_hw(struct net_device *dev)
@@ -1060,12 +1070,13 @@ static void xl_freemem(struct net_device *dev)
}
/* unmap ring */
- pci_unmap_single(xl_priv->pdev,xl_priv->rx_ring_dma_addr, sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE, PCI_DMA_FROMDEVICE) ;
-
- pci_unmap_single(xl_priv->pdev,xl_priv->tx_ring_dma_addr, sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE, PCI_DMA_TODEVICE) ;
+ dma_free_coherent(&xl_priv->pdev->dev,
+ sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE,
+ xl_priv->xl_rx_ring, xl_priv->rx_ring_dma_addr);
- kfree(xl_priv->xl_rx_ring) ;
- kfree(xl_priv->xl_tx_ring) ;
+ dma_free_coherent(&xl_priv->pdev->dev,
+ sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE,
+ xl_priv->xl_tx_ring, xl_priv->tx_ring_dma_addr);
return ;
}
diff --git a/drivers/net/tokenring/3c359.h b/drivers/net/tokenring/3c359.h
index bcb1a6b..baefdd3 100644
--- a/drivers/net/tokenring/3c359.h
+++ b/drivers/net/tokenring/3c359.h
@@ -282,8 +282,8 @@ struct xl_private {
unsigned char xl_functional_addr[4] ;
u16 xl_addr_table_addr, xl_parms_addr ;
u8 xl_laa[6] ;
- u32 rx_ring_dma_addr ;
- u32 tx_ring_dma_addr ;
+ dma_addr_t rx_ring_dma_addr;
+ dma_addr_t tx_ring_dma_addr;
/* firmware section */
const struct firmware *fw;
--
1.7.5.4
^ permalink raw reply related
* [PATCH v2 08/46] net/wireless: b43: fix DMA direction for RX buffers
From: Michał Mirosław @ 2011-07-11 0:52 UTC (permalink / raw)
To: netdev; +Cc: Stefano Brivio, linux-wireless
In-Reply-To: <cover.1310339688.git.mirq-linux@rere.qmqm.pl>
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
drivers/net/wireless/b43/dma.c | 9 +++++----
1 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 7a09a46..15b11f0 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -336,8 +336,9 @@ static inline
dmaaddr = dma_map_single(ring->dev->dev->dma_dev,
buf, len, DMA_TO_DEVICE);
} else {
+ /* DMA_BIDIRECTIONAL because of b43_poison_rx_buffer() */
dmaaddr = dma_map_single(ring->dev->dev->dma_dev,
- buf, len, DMA_FROM_DEVICE);
+ buf, len, DMA_BIDIRECTIONAL);
}
return dmaaddr;
@@ -352,7 +353,7 @@ static inline
addr, len, DMA_TO_DEVICE);
} else {
dma_unmap_single(ring->dev->dev->dma_dev,
- addr, len, DMA_FROM_DEVICE);
+ addr, len, DMA_BIDIRECTIONAL);
}
}
@@ -362,7 +363,7 @@ static inline
{
B43_WARN_ON(ring->tx);
dma_sync_single_for_cpu(ring->dev->dev->dma_dev,
- addr, len, DMA_FROM_DEVICE);
+ addr, len, DMA_BIDIRECTIONAL);
}
static inline
@@ -371,7 +372,7 @@ static inline
{
B43_WARN_ON(ring->tx);
dma_sync_single_for_device(ring->dev->dev->dma_dev,
- addr, len, DMA_FROM_DEVICE);
+ addr, len, DMA_BIDIRECTIONAL);
}
static inline
--
1.7.5.4
^ permalink raw reply related
* [PATCH v2 01/46] net: introduce __netdev_alloc_skb_aligned()
From: Michał Mirosław @ 2011-07-11 0:52 UTC (permalink / raw)
To: netdev
In-Reply-To: <cover.1310339688.git.mirq-linux@rere.qmqm.pl>
Introduce __netdev_alloc_skb_aligned() to return skb with skb->data
aligned at specified 2^n multiple.
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
include/linux/skbuff.h | 27 +++++++++++++++++++++++++++
1 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 32ada53..c873897 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1561,6 +1561,33 @@ extern struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
unsigned int length, gfp_t gfp_mask);
/**
+ * __netdev_alloc_skb_aligned - allocate an skbuff for rx on a specific device
+ * @dev: network device to receive on
+ * @length: length to allocate
+ * @align: required skb->data alignment
+ * @gfp_mask: get_free_pages mask, passed to alloc_skb
+ *
+ * Allocate a new &sk_buff and assign it a usage count of one. The
+ * buffer has unspecified headroom built in. Users should allocate
+ * the headroom they think they need without accounting for the
+ * built in space. The built in space is used for optimisations.
+ *
+ * %NULL is returned if there is no free memory.
+ */
+static inline struct sk_buff *__netdev_alloc_skb_aligned(struct net_device *dev,
+ unsigned int length, unsigned int align, gfp_t gfp_mask)
+{
+ struct sk_buff *skb;
+
+ skb = __alloc_skb(length + NET_SKB_PAD + align, gfp_mask, 0, NUMA_NO_NODE);
+ if (likely(skb)) {
+ skb_reserve(skb, PTR_ALIGN(skb->data + NET_SKB_PAD, align) - skb->data);
+ skb->dev = dev;
+ }
+ return skb;
+}
+
+/**
* netdev_alloc_skb - allocate an skbuff for rx on a specific device
* @dev: network device to receive on
* @length: length to allocate
--
1.7.5.4
^ permalink raw reply related
* [PATCH v2 00/46] Clean up RX copybreak and DMA handling
From: Michał Mirosław @ 2011-07-11 0:52 UTC (permalink / raw)
To: netdev
Quick rx_copybreak cleaning turned out to rise more dust around...
Most drivers use dma_sync_single_to_device() for buffers that are
written only by device. That's probably because of bad example in
current Documentation/DMA-API-HOWTO.txt. Why is it bad? It unnecessarily
flushes cachelines and CPU write buffers for memory that is not used
by the hardware. Documentation/DMA-API.txt (part Id) describes exactly
when streaming DMA buffers should be synced and in which direction.
Syncing DMA_FROM_DEVICE mappings for device is not among them.
A lot of drivers drop packets already DMA'd in on memory pressure. This
is suboptimal:
1. under packet storm and memory pressure NIC keeps generating interrupts
(if non-NAPI) and indicating new buffers because it always has free
RX buffers --- this only wastes CPU and bus bandwidth transferring
data that is going to be immediately discarded;
2. for users of swap over network (NBD, NFS - assumming those get
fixed, or maybe FCoE?) this can cause deadlock if the packets
(acks maybe?) are needed to reclaim memory.
It unlikely that you'll ever hit the dark scenarios above, but if you do
you'll have a hard time debugging.
Menu:
1..2:
wrap code commonly used in drivers into generic functions
3..4:
remove dma_sync_to_device(DMA_FROM_DEVICE) from drivers not
converted to common rx handling functions
5..10:
fix various DMA API usage bugs in rx handling code
11..14:
clean up rx buffer allocation in sun* drivers
15:
b43: use kfree_skb() if the skb is known not to have been used
16:
cxgb3: remove code dropping packets on memory pressure in driver
46:
mark some drivers that drop packets from rx queue head when under
memory pressure
Left out for later:
17..34:
convert multiple drivers to common rx_copybreak handling
35..45:
convert multiple drivers to common rx_copybreak handling; those
drivers drop rxed packets when under memory pressure
Patches 17..45 are more-or-less templated and in the same spirit as
the earlier version.
[davem: I plan send them after/if you agree to take patch 2. Or earlier,
if you want them all at once anyway.]
Best Regards,
Michał Mirosław
---
Michał Mirosław (46):
net: introduce __netdev_alloc_skb_aligned()
net: wrap common patterns of rx handler code
net drivers: remove unnecessary dma_sync_to_device(DMA_FROM_DEVICE)
net/wireless: p54: remove useless
dma_sync_single_for_device(DMA_FROM_DEVICE)
net: bnx2x: fix DMA sync direction
net/tokenring: 3c359: fix DMA API usage
net/wireless: ath9k: fix DMA API usage
net/wireless: b43: fix DMA direction for RX buffers
net: octeon_mgmt: fix DMA unmap size
net: jme: convert to generic DMA API
net: sungem: cleanup RX skb allocation
net: sunhme: cleanup RX skb allocation
net: sunbmac: cleanup RX skb allocation
net: sunbmac: cleanup magic '34'
net/wireless: b43: use kfree_skb() for untouched skbs
net: cxgb3: don't drop packets on memory pressure in driver
net: 3c59x: use common rx_copybreak handling
net: epic100: use common rx_copybreak handling
net: fealnx: use common rx_copybreak handling
net: hamachi: use common rx_copybreak handling
net: bcm63xx: use common rx_copybreak handling
net: chelsio: use common rx_copybreak handling
net: cxgb3: use common rx_copybreak handling
net: dl2k: use common rx_copybreak handling
net: natsemi: use common rx_copybreak handling
net: sis190: use common rx_copybreak handling
net: starfire: use common rx_copybreak handling
net: sundance: use common rx_copybreak handling
net: tulip/interrupt: use common rx_copybreak handling
net: tulip/winbond-840: use common rx_copybreak handling
net: typhoon: use common rx_copybreak handling
net: via-rhine: use common rx_copybreak handling
net: via-velocity: use common rx_copybreak handling
net: yellowfin: use common rx_copybreak handling
net: lib82596: use common rx_copybreak handling [strict refill!]
net: pcnet32: use common rx_copybreak handling [strict refill!]
net: sgiseeq: use common rx_copybreak handling [strict refill!]
net: tulip/de2104x: use common rx_copybreak handling [strict refill!]
net: sunhme: use common rx_copybreak handling [strict refill!]
net: sunbmac: use common rx_copybreak handling [strict refill!]
net: rrunner: use common rx_copybreak handling [strict refill!]
net: greth: use common rx_copybreak handling [strict refill!]
net: sunbmac: use common rx_copybreak handling [strict refill!]
net: tokenring/3c359: use common rx_copybreak handling [strict
refill!]
net/wireless: adm8211: use common rx_copybreak handling [strict
refill!]
net: mark drivers that drop packets from rx queue head under memory
pressure
drivers/net/3c59x.c | 23 +---
drivers/net/arm/ep93xx_eth.c | 6 +-
drivers/net/b44.c | 4 -
drivers/net/bcm63xx_enet.c | 28 +----
drivers/net/bnx2.c | 7 +-
drivers/net/bnx2x/bnx2x_cmn.c | 5 +-
drivers/net/bnx2x/bnx2x_cmn.h | 5 -
drivers/net/bnx2x/bnx2x_ethtool.c | 2 +-
drivers/net/cassini.c | 15 +--
drivers/net/chelsio/sge.c | 42 +------
drivers/net/cxgb3/sge.c | 57 ++-------
drivers/net/dl2k.c | 28 +----
drivers/net/e100.c | 3 -
drivers/net/e1000e/netdev.c | 4 +-
drivers/net/epic100.c | 32 ++----
drivers/net/fealnx.c | 40 ++-----
drivers/net/greth.c | 67 ++++-------
drivers/net/hamachi.c | 42 +------
drivers/net/jme.c | 40 +++----
drivers/net/lib82596.c | 70 +++--------
drivers/net/mlx4/en_rx.c | 8 +-
drivers/net/natsemi.c | 37 ++-----
drivers/net/octeon/octeon_mgmt.c | 9 +-
drivers/net/pcnet32.c | 53 ++-------
drivers/net/qlge/qlge_main.c | 11 --
drivers/net/r8169.c | 4 +-
drivers/net/rrunner.c | 66 +++--------
drivers/net/s2io.c | 6 +-
drivers/net/sgiseeq.c | 42 +++-----
drivers/net/sis190.c | 40 +------
drivers/net/skge.c | 6 +-
drivers/net/sky2.c | 4 +-
drivers/net/starfire.c | 28 ++---
drivers/net/sunbmac.c | 78 +++----------
drivers/net/sunbmac.h | 18 +---
drivers/net/sundance.c | 26 +---
drivers/net/sungem.c | 84 +++----------
drivers/net/sungem.h | 4 +-
drivers/net/sunhme.c | 61 ++--------
drivers/net/sunhme.h | 14 +--
drivers/net/tg3.c | 3 +-
drivers/net/tokenring/3c359.c | 74 ++++++------
drivers/net/tokenring/3c359.h | 4 +-
drivers/net/tokenring/olympic.c | 8 +-
drivers/net/tulip/de2104x.c | 39 ++-----
drivers/net/tulip/interrupt.c | 77 +++----------
drivers/net/tulip/winbond-840.c | 28 +----
drivers/net/typhoon.c | 26 +---
drivers/net/via-rhine.c | 38 +-----
drivers/net/via-velocity.c | 61 ++--------
drivers/net/vxge/vxge-main.c | 6 +-
drivers/net/wireless/adm8211.c | 41 +------
drivers/net/wireless/ath/ath9k/ar9003_mac.c | 4 +-
drivers/net/wireless/ath/ath9k/ar9003_mac.h | 2 +-
drivers/net/wireless/ath/ath9k/recv.c | 10 +-
drivers/net/wireless/b43/dma.c | 15 ++-
drivers/net/wireless/b43legacy/dma.c | 19 ---
drivers/net/wireless/p54/p54pci.c | 2 -
drivers/net/wireless/p54/txrx.c | 22 ++--
drivers/net/yellowfin.c | 27 +----
include/linux/skbuff.h | 169 +++++++++++++++++++++++++++
61 files changed, 586 insertions(+), 1208 deletions(-)
--
1.7.5.4
^ permalink raw reply
* [PATCH v2 02/46] net: wrap common patterns of rx handler code
From: Michał Mirosław @ 2011-07-11 0:52 UTC (permalink / raw)
To: netdev
In-Reply-To: <cover.1310339688.git.mirq-linux@rere.qmqm.pl>
Introduce dev_skb_finish_rx_dma() and dev_skb_finish_rx_dma_refill() ---
two common patterns for rx handling as seen in various network drivers
that implement rx_copybreak idea (copying smaller packets, passing larger
ones in original skb).
The common pattern (as implemented in dev_skb_finish_rx_dma()) is:
if (packet len < threshold)
allocate new, smaller skb
sync DMA buffer to cpu
copy packet's data
give DMA buffer back to device
pass new skb
reuse buffer in rx ring
else (or if skb alloc for copy failed)
unmap DMA buffer
pass skb
remove buffer from rx ring
[refill rx ring later]
This scheme is modified by some drivers to immediately refill rx slot before
passing original rx skb up the stack. Those drivers have also a problem that
they drop packets from the head of the queue when that allocation fails. This
forces unnecessary retransmits and can deadlock if the device is used for
swapping over network. To mark this case, dev_skb_finish_rx_dma_refill()
implementing it, is marked as deprecated to encourage driver maintainers to
look into the matter.
Those functions are called from rx handler hot path and have a lot of arguments,
and so are inlined. This should allow compiler to better optimize the code with
calling code.
v2:
- remove unnecessary dma_sync_single_for_device()
[See: DMA-API.txt, part. Id, DMA_FROM_DEVICE description]
- check dma_mapping_error() in dev_skb_finish_rx_dma_refill()
- handle RX_OFFSET (padding inserted by hardware before packet's data)
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
include/linux/skbuff.h | 142 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 142 insertions(+), 0 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index c873897..bf51006 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -29,6 +29,7 @@
#include <linux/rcupdate.h>
#include <linux/dmaengine.h>
#include <linux/hrtimer.h>
+#include <linux/dma-mapping.h>
/* Don't change this without changing skb_csum_unnecessary! */
#define CHECKSUM_NONE 0
@@ -2310,5 +2311,146 @@ static inline void skb_checksum_none_assert(struct sk_buff *skb)
bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off);
+/**
+ * __dev_skb_finish_rx_dma - finish skb after DMA'd RX
+ * @skb: skb to finish
+ * @len: packet data length
+ * @copybreak: maximum packet size to copy
+ * @rx_offset: count of bytes prepended to packet's data by hardware
+ * @dma_dev: device used for DMA
+ * @dma_buf: DMA mapping address
+ * @dma_len: DMA mapping length
+ *
+ * This function finishes DMA mapping (sync for copied, unmap otherwise) for
+ * a packet and copies it to new skb if its size is at or below @copybreak
+ * threshold.
+ *
+ * Returns new skb or NULL if the copy wasn't made.
+ */
+static inline struct sk_buff *__dev_skb_finish_rx_dma(struct sk_buff *skb,
+ unsigned int len, unsigned int copybreak, unsigned int rx_offset,
+ struct device *dma_dev, dma_addr_t dma_buf, size_t dma_len)
+{
+ if (len < copybreak) {
+ struct sk_buff *skb2 = netdev_alloc_skb_ip_align(skb->dev, len);
+ if (likely(skb2)) {
+ dma_sync_single_for_cpu(dma_dev, dma_buf,
+ len + rx_offset, DMA_FROM_DEVICE);
+ skb_copy_to_linear_data(skb2, skb->data, len);
+ return skb2;
+ }
+ }
+
+ /* else or copy failed */
+
+ dma_unmap_single(dma_dev, dma_buf, dma_len, DMA_FROM_DEVICE);
+ return NULL;
+}
+
+/**
+ * dev_skb_finish_rx_dma - finish skb after DMA'd RX
+ * @pskb: pointer to variable holding skb to finish
+ * @len: packet data length
+ * @copybreak: maximum packet size to copy
+ * @rx_offset: count of bytes prepended to packet's data by hardware
+ * @dma_dev: device used for DMA
+ * @dma_buf: DMA mapping address
+ * @dma_len: DMA mapping length
+ *
+ * This function finishes DMA mapping (sync for copied, unmap otherwise) for
+ * a packet and copies it to new skb if its size is at or below @copybreak
+ * threshold. Like __dev_skb_finish_rx_dma().
+ *
+ * Returns the skb - old or copied. *pskb is cleared if the skb wasn't copied.
+ */
+static inline struct sk_buff *dev_skb_finish_rx_dma(struct sk_buff **pskb,
+ unsigned int len, unsigned int copybreak, unsigned int rx_offset,
+ struct device *dma_dev, dma_addr_t dma_buf, size_t dma_len)
+{
+ struct sk_buff *skb2;
+
+ skb2 = __dev_skb_finish_rx_dma(*pskb, len, copybreak, rx_offset,
+ dma_dev, dma_buf, dma_len);
+
+ if (!skb2) {
+ /* not copied */
+ skb2 = *pskb;
+ *pskb = NULL;
+ }
+
+ skb_put(skb2, len);
+ return skb2;
+}
+
+/**
+ * dev_skb_finish_rx_dma_refill - finish skb after DMA'd RX and refill the slot
+ * @pskb: pointer to variable holding skb to finish
+ * @len: packet data length
+ * @copybreak: maximum packet size to copy
+ * @ip_align: new skb's alignment offset
+ * @rx_offset: count of bytes prepended by HW before packet's data
+ * @dma_dev: device used for DMA
+ * @dma_buf: DMA mapping address
+ * @dma_len: DMA mapping length
+ * @dma_align: required DMA buffer alignment for new skbs
+ *
+ * This function finishes DMA mapping (sync for copied, unmap otherwise) for
+ * a packet and copies it to new skb if its size is at or below @copybreak
+ * threshold. Like __dev_skb_finish_rx_dma().
+ *
+ * *pskb is filled with new mapped skb if the skb wasn't copied.
+ * Returns the skb - old or copied, or NULL if refill failed.
+ *
+ * NOTE:
+ * This will effectively drop the packet in case of memory pressure. This
+ * might not be wanted when swapping over network. It's better to throttle
+ * the receiver queue (refill later) as the packet might be needed to
+ * reclaim some memory.
+ */
+static inline __deprecated struct sk_buff *dev_skb_finish_rx_dma_refill(
+ struct sk_buff **pskb, unsigned int len, unsigned int copybreak,
+ unsigned int ip_align, unsigned int rx_offset,
+ struct device *dma_dev, dma_addr_t *dma_buf, size_t dma_len,
+ size_t dma_align)
+{
+ struct sk_buff *skb;
+
+ skb = __dev_skb_finish_rx_dma(*pskb, len, copybreak, rx_offset,
+ dma_dev, *dma_buf, dma_len);
+
+ if (!skb) {
+ /* not copied */
+ skb = *pskb;
+ /* netdev_alloc_skb_ip_align() */
+ *pskb = __netdev_alloc_skb_aligned(skb->dev, dma_len + ip_align,
+ dma_align, GFP_ATOMIC);
+ if (likely(*pskb))
+ skb_reserve(*pskb, ip_align + rx_offset);
+ else {
+ /* no memory - drop packet */
+ *pskb = skb;
+ skb = NULL;
+ }
+
+ *dma_buf = dma_map_single(dma_dev, (*pskb)->data - rx_offset,
+ dma_len, DMA_FROM_DEVICE);
+ if (dma_mapping_error(dma_dev, *dma_buf)) {
+ BUG_ON(!skb); /* caller can't handle this case */
+ kfree_skb(*pskb);
+ *pskb = skb;
+ skb = NULL;
+ *dma_buf = dma_map_single(dma_dev,
+ (*pskb)->data - rx_offset, dma_len,
+ DMA_FROM_DEVICE);
+ BUG_ON(dma_mapping_error(dma_dev, *dma_buf));
+ }
+ }
+
+ if (likely(skb))
+ skb_put(skb, len);
+
+ return skb;
+}
+
#endif /* __KERNEL__ */
#endif /* _LINUX_SKBUFF_H */
--
1.7.5.4
^ permalink raw reply related
* [PATCH v2 04/46] net/wireless: p54: remove useless dma_sync_single_for_device(DMA_FROM_DEVICE)
From: Michał Mirosław @ 2011-07-11 0:52 UTC (permalink / raw)
To: netdev; +Cc: Christian Lamparter, John W. Linville, linux-wireless
In-Reply-To: <cover.1310339688.git.mirq-linux@rere.qmqm.pl>
Also constify pointers used in frame parsers to verify assumptions.
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
drivers/net/wireless/p54/p54pci.c | 2 --
drivers/net/wireless/p54/txrx.c | 22 +++++++++++-----------
2 files changed, 11 insertions(+), 13 deletions(-)
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index 1b75317..4491d33 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -229,8 +229,6 @@ static void p54p_check_rx_ring(struct ieee80211_hw *dev, u32 *index,
desc->host_addr = cpu_to_le32(0);
} else {
skb_trim(skb, 0);
- pci_dma_sync_single_for_device(priv->pdev, dma_addr,
- priv->common.rx_mtu + 32, PCI_DMA_FROMDEVICE);
desc->len = cpu_to_le16(priv->common.rx_mtu + 32);
}
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c
index 042842e..b7ecd89 100644
--- a/drivers/net/wireless/p54/txrx.c
+++ b/drivers/net/wireless/p54/txrx.c
@@ -325,7 +325,7 @@ static void p54_pspoll_workaround(struct p54_common *priv, struct sk_buff *skb)
static int p54_rx_data(struct p54_common *priv, struct sk_buff *skb)
{
- struct p54_rx_data *hdr = (struct p54_rx_data *) skb->data;
+ const struct p54_rx_data *hdr = (void *)skb->data;
struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
u16 freq = le16_to_cpu(hdr->freq);
size_t header_len = sizeof(*hdr);
@@ -387,8 +387,8 @@ static int p54_rx_data(struct p54_common *priv, struct sk_buff *skb)
static void p54_rx_frame_sent(struct p54_common *priv, struct sk_buff *skb)
{
- struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
- struct p54_frame_sent *payload = (struct p54_frame_sent *) hdr->data;
+ const struct p54_hdr *hdr = (void *)skb->data;
+ const struct p54_frame_sent *payload = (void *)hdr->data;
struct ieee80211_tx_info *info;
struct p54_hdr *entry_hdr;
struct p54_tx_data *entry_data;
@@ -481,8 +481,8 @@ static void p54_rx_frame_sent(struct p54_common *priv, struct sk_buff *skb)
static void p54_rx_eeprom_readback(struct p54_common *priv,
struct sk_buff *skb)
{
- struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
- struct p54_eeprom_lm86 *eeprom = (struct p54_eeprom_lm86 *) hdr->data;
+ const struct p54_hdr *hdr = (void *)skb->data;
+ const struct p54_eeprom_lm86 *eeprom = (void *)hdr->data;
struct sk_buff *tmp;
if (!priv->eeprom)
@@ -504,8 +504,8 @@ static void p54_rx_eeprom_readback(struct p54_common *priv,
static void p54_rx_stats(struct p54_common *priv, struct sk_buff *skb)
{
- struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
- struct p54_statistics *stats = (struct p54_statistics *) hdr->data;
+ const struct p54_hdr *hdr = (void *)skb->data;
+ const struct p54_statistics *stats = (void *)hdr->data;
struct sk_buff *tmp;
u32 tsf32;
@@ -529,8 +529,8 @@ static void p54_rx_stats(struct p54_common *priv, struct sk_buff *skb)
static void p54_rx_trap(struct p54_common *priv, struct sk_buff *skb)
{
- struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
- struct p54_trap *trap = (struct p54_trap *) hdr->data;
+ const struct p54_hdr *hdr = (void *)skb->data;
+ const struct p54_trap *trap = (void *)hdr->data;
u16 event = le16_to_cpu(trap->event);
u16 freq = le16_to_cpu(trap->frequency);
@@ -565,7 +565,7 @@ static void p54_rx_trap(struct p54_common *priv, struct sk_buff *skb)
static int p54_rx_control(struct p54_common *priv, struct sk_buff *skb)
{
- struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
+ const struct p54_hdr *hdr = (void *)skb->data;
switch (le16_to_cpu(hdr->type)) {
case P54_CONTROL_TYPE_TXDONE:
@@ -595,7 +595,7 @@ static int p54_rx_control(struct p54_common *priv, struct sk_buff *skb)
int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb)
{
struct p54_common *priv = dev->priv;
- u16 type = le16_to_cpu(*((__le16 *)skb->data));
+ u16 type = le16_to_cpu(*(const __le16 *)skb->data);
if (type & P54_HDR_FLAG_CONTROL)
return p54_rx_control(priv, skb);
--
1.7.5.4
^ permalink raw reply related
* [PATCH v2 07/46] net/wireless: ath9k: fix DMA API usage
From: Michał Mirosław @ 2011-07-11 0:52 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: Luis R. Rodriguez, Jouni Malinen, Vasanthakumar Thiagarajan,
Senthil Balasubramanian, linux-wireless-u79uwXL29TY76Z2rM5mHXA,
ath9k-devel-xDcbHBWguxHbcTqmT+pZeQ
In-Reply-To: <cover.1310339688.git.mirq-linux-CoA6ZxLDdyEEUmgCuDUIdw@public.gmane.org>
Also constify buf_addr for ath9k_hw_process_rxdesc_edma() to verify
assumptions --- dma_sync_single_for_device() call can be removed.
Signed-off-by: Michał Mirosław <mirq-linux-CoA6ZxLDdyEEUmgCuDUIdw@public.gmane.org>
---
drivers/net/wireless/ath/ath9k/ar9003_mac.c | 4 ++--
drivers/net/wireless/ath/ath9k/ar9003_mac.h | 2 +-
drivers/net/wireless/ath/ath9k/recv.c | 10 +++-------
3 files changed, 6 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 575e185..2d211b6 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -524,9 +524,9 @@ void ath9k_hw_addrxbuf_edma(struct ath_hw *ah, u32 rxdp,
EXPORT_SYMBOL(ath9k_hw_addrxbuf_edma);
int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
- void *buf_addr)
+ const void *buf_addr)
{
- struct ar9003_rxs *rxsp = (struct ar9003_rxs *) buf_addr;
+ const struct ar9003_rxs *rxsp = buf_addr;
unsigned int phyerr;
/* TODO: byte swap on big endian for ar9300_10 */
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.h b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
index c504493..c310edc 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
@@ -114,7 +114,7 @@ void ath9k_hw_addrxbuf_edma(struct ath_hw *ah, u32 rxdp,
int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah,
struct ath_rx_status *rxs,
- void *buf_addr);
+ const void *buf_addr);
void ath9k_hw_reset_txstatus_ring(struct ath_hw *ah);
void ath9k_hw_setup_statusring(struct ath_hw *ah, void *ts_start,
u32 ts_paddr_start,
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 70dc8ec..c5f46d5 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -156,7 +156,7 @@ static bool ath_rx_edma_buf_link(struct ath_softc *sc,
ATH_RXBUF_RESET(bf);
memset(skb->data, 0, ah->caps.rx_status_len);
dma_sync_single_for_device(sc->dev, bf->bf_buf_addr,
- ah->caps.rx_status_len, DMA_TO_DEVICE);
+ ah->caps.rx_status_len, DMA_BIDIRECTIONAL);
SKB_CB_ATHBUF(skb) = bf;
ath9k_hw_addrxbuf_edma(ah, bf->bf_buf_addr, qtype);
@@ -684,15 +684,11 @@ static bool ath_edma_get_buffers(struct ath_softc *sc,
BUG_ON(!bf);
dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr,
- common->rx_bufsize, DMA_FROM_DEVICE);
+ common->rx_bufsize, DMA_BIDIRECTIONAL);
ret = ath9k_hw_process_rxdesc_edma(ah, NULL, skb->data);
- if (ret == -EINPROGRESS) {
- /*let device gain the buffer again*/
- dma_sync_single_for_device(sc->dev, bf->bf_buf_addr,
- common->rx_bufsize, DMA_FROM_DEVICE);
+ if (ret == -EINPROGRESS)
return false;
- }
__skb_unlink(skb, &rx_edma->rx_fifo);
if (ret == -EINVAL) {
--
1.7.5.4
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 03/46] net drivers: remove unnecessary dma_sync_to_device(DMA_FROM_DEVICE)
From: Michał Mirosław @ 2011-07-11 0:52 UTC (permalink / raw)
To: netdev
Cc: linux-wireless, Eilon Greenstein, Gary Zambrano,
Stephen Hemminger, Stefano Brivio, e1000-devel, Matt Carlson,
Jesse Brandeburg, Francois Romieu, Realtek linux nic maintainers,
John W. Linville, Ron Mercer, Michael Chan, Jitendra Kalsaria,
Divy Le Ray, Bruce Allan, Hartley Sweeten, John Ronciak,
Jon Mason, linux-driver, Larry Finger
In-Reply-To: <cover.1310339688.git.mirq-linux@rere.qmqm.pl>
dma_sync_to_device() is not needed when only device modifies the buffer.
See: DMA-API.txt, part. Id, DMA_FROM_DEVICE description.
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
drivers/net/arm/ep93xx_eth.c | 3 ---
drivers/net/b44.c | 4 ----
drivers/net/bnx2.c | 4 ----
drivers/net/bnx2x/bnx2x_cmn.h | 5 -----
drivers/net/cassini.c | 12 ------------
drivers/net/cxgb3/sge.c | 3 ---
drivers/net/e100.c | 3 ---
drivers/net/e1000e/netdev.c | 4 +---
drivers/net/mlx4/en_rx.c | 2 --
drivers/net/qlge/qlge_main.c | 11 -----------
drivers/net/r8169.c | 1 -
drivers/net/s2io.c | 6 +-----
drivers/net/skge.c | 3 ---
drivers/net/sky2.c | 2 --
drivers/net/tg3.c | 1 -
drivers/net/tokenring/olympic.c | 6 ------
drivers/net/vxge/vxge-main.c | 3 ---
drivers/net/wireless/b43legacy/dma.c | 19 -------------------
18 files changed, 2 insertions(+), 90 deletions(-)
diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c
index 4317af8..ba3bf43 100644
--- a/drivers/net/arm/ep93xx_eth.c
+++ b/drivers/net/arm/ep93xx_eth.c
@@ -289,9 +289,6 @@ static int ep93xx_rx(struct net_device *dev, int processed, int budget)
dma_sync_single_for_cpu(dev->dev.parent, rxd->buf_addr,
length, DMA_FROM_DEVICE);
skb_copy_to_linear_data(skb, ep->rx_buf[entry], length);
- dma_sync_single_for_device(dev->dev.parent,
- rxd->buf_addr, length,
- DMA_FROM_DEVICE);
skb_put(skb, length);
skb->protocol = eth_type_trans(skb, dev);
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 6c4ef96..033029f 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -739,10 +739,6 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
b44_sync_dma_desc_for_device(bp->sdev, bp->rx_ring_dma,
dest_idx * sizeof(*dest_desc),
DMA_BIDIRECTIONAL);
-
- dma_sync_single_for_device(bp->sdev->dma_dev, dest_map->mapping,
- RX_PKT_BUF_SZ,
- DMA_FROM_DEVICE);
}
static int b44_rx(struct b44 *bp, int budget)
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 7915d14..d627886 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -2927,10 +2927,6 @@ bnx2_reuse_rx_skb(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr,
cons_rx_buf = &rxr->rx_buf_ring[cons];
prod_rx_buf = &rxr->rx_buf_ring[prod];
- dma_sync_single_for_device(&bp->pdev->dev,
- dma_unmap_addr(cons_rx_buf, mapping),
- BNX2_RX_OFFSET + BNX2_RX_COPY_THRESH, PCI_DMA_FROMDEVICE);
-
rxr->rx_prod_bseq += bp->rx_buf_use_size;
prod_rx_buf->skb = skb;
diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h
index c016e20..c9e49a0 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/bnx2x/bnx2x_cmn.h
@@ -923,16 +923,11 @@ static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp,
static inline void bnx2x_reuse_rx_skb(struct bnx2x_fastpath *fp,
u16 cons, u16 prod)
{
- struct bnx2x *bp = fp->bp;
struct sw_rx_bd *cons_rx_buf = &fp->rx_buf_ring[cons];
struct sw_rx_bd *prod_rx_buf = &fp->rx_buf_ring[prod];
struct eth_rx_bd *cons_bd = &fp->rx_desc_ring[cons];
struct eth_rx_bd *prod_bd = &fp->rx_desc_ring[prod];
- dma_sync_single_for_device(&bp->pdev->dev,
- dma_unmap_addr(cons_rx_buf, mapping),
- RX_COPY_THRESH, DMA_FROM_DEVICE);
-
dma_unmap_addr_set(prod_rx_buf, mapping,
dma_unmap_addr(cons_rx_buf, mapping));
prod_rx_buf->skb = cons_rx_buf->skb;
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index b414f5a..788ab13 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -1997,8 +1997,6 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc,
PCI_DMA_FROMDEVICE);
addr = cas_page_map(page->buffer);
memcpy(p, addr + off, i);
- pci_dma_sync_single_for_device(cp->pdev, page->dma_addr + off, i,
- PCI_DMA_FROMDEVICE);
cas_page_unmap(addr);
RX_USED_ADD(page, 0x100);
p += hlen;
@@ -2032,8 +2030,6 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc,
if (p == (char *) skb->data) { /* not split */
addr = cas_page_map(page->buffer);
memcpy(p, addr + off, RX_COPY_MIN);
- pci_dma_sync_single_for_device(cp->pdev, page->dma_addr + off, i,
- PCI_DMA_FROMDEVICE);
cas_page_unmap(addr);
off += RX_COPY_MIN;
swivel = RX_COPY_MIN;
@@ -2063,9 +2059,6 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc,
pci_dma_sync_single_for_cpu(cp->pdev, page->dma_addr,
hlen + cp->crc_size,
PCI_DMA_FROMDEVICE);
- pci_dma_sync_single_for_device(cp->pdev, page->dma_addr,
- hlen + cp->crc_size,
- PCI_DMA_FROMDEVICE);
skb_shinfo(skb)->nr_frags++;
skb->data_len += hlen;
@@ -2106,8 +2099,6 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc,
PCI_DMA_FROMDEVICE);
addr = cas_page_map(page->buffer);
memcpy(p, addr + off, i);
- pci_dma_sync_single_for_device(cp->pdev, page->dma_addr + off, i,
- PCI_DMA_FROMDEVICE);
cas_page_unmap(addr);
if (p == (char *) skb->data) /* not split */
RX_USED_ADD(page, cp->mtu_stride);
@@ -2124,9 +2115,6 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc,
PCI_DMA_FROMDEVICE);
addr = cas_page_map(page->buffer);
memcpy(p, addr, dlen + cp->crc_size);
- pci_dma_sync_single_for_device(cp->pdev, page->dma_addr,
- dlen + cp->crc_size,
- PCI_DMA_FROMDEVICE);
cas_page_unmap(addr);
RX_USED_ADD(page, dlen + cp->crc_size);
}
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index 76bf589..3196fdd 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -517,9 +517,6 @@ nomem: q->alloc_failed++;
dma_unmap_addr_set(sd, dma_addr, mapping);
add_one_rx_chunk(mapping, d, q->gen);
- pci_dma_sync_single_for_device(adap->pdev, mapping,
- q->buf_size - SGE_PG_RSVD,
- PCI_DMA_FROMDEVICE);
} else {
void *buf_start;
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index c1352c6..73034af 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -1944,9 +1944,6 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx,
if (ioread8(&nic->csr->scb.status) & rus_no_res)
nic->ru_running = RU_SUSPENDED;
- pci_dma_sync_single_for_device(nic->pdev, rx->dma_addr,
- sizeof(struct rfd),
- PCI_DMA_FROMDEVICE);
return -ENODATA;
}
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index ed7a93d..f9b16cf 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -1172,12 +1172,10 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
* very long
*/
dma_sync_single_for_cpu(&pdev->dev, ps_page->dma,
- PAGE_SIZE, DMA_FROM_DEVICE);
+ l1, DMA_FROM_DEVICE);
vaddr = kmap_atomic(ps_page->page, KM_SKB_DATA_SOFTIRQ);
memcpy(skb_tail_pointer(skb), vaddr, l1);
kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ);
- dma_sync_single_for_device(&pdev->dev, ps_page->dma,
- PAGE_SIZE, DMA_FROM_DEVICE);
/* remove the CRC */
if (!(adapter->flags2 & FLAG2_CRC_STRIPPING))
diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c
index 5197b50..ee15295 100644
--- a/drivers/net/mlx4/en_rx.c
+++ b/drivers/net/mlx4/en_rx.c
@@ -483,8 +483,6 @@ static struct sk_buff *mlx4_en_rx_skb(struct mlx4_en_priv *priv,
dma_sync_single_for_cpu(&mdev->pdev->dev, dma, length,
DMA_FROM_DEVICE);
skb_copy_to_linear_data(skb, va, length);
- dma_sync_single_for_device(&mdev->pdev->dev, dma, length,
- DMA_FROM_DEVICE);
skb->tail += length;
} else {
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 68fbfac..48dd59b 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -1195,9 +1195,6 @@ static void ql_update_lbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
rx_ring->lbq_buf_size);
*lbq_desc->addr = cpu_to_le64(map);
- pci_dma_sync_single_for_device(qdev->pdev, map,
- rx_ring->lbq_buf_size,
- PCI_DMA_FROMDEVICE);
clean_idx++;
if (clean_idx == rx_ring->lbq_len)
clean_idx = 0;
@@ -1801,14 +1798,6 @@ static struct sk_buff *ql_build_rx_skb(struct ql_adapter *qdev,
PCI_DMA_FROMDEVICE);
memcpy(skb_put(skb, length),
sbq_desc->p.skb->data, length);
- pci_dma_sync_single_for_device(qdev->pdev,
- dma_unmap_addr
- (sbq_desc,
- mapaddr),
- dma_unmap_len
- (sbq_desc,
- maplen),
- PCI_DMA_FROMDEVICE);
} else {
netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
"%d bytes in a single small buffer.\n",
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index ef1a43d..e2c2884 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -5005,7 +5005,6 @@ static struct sk_buff *rtl8169_try_rx_copy(void *data,
skb = netdev_alloc_skb_ip_align(tp->dev, pkt_size);
if (skb)
memcpy(skb->data, data, pkt_size);
- dma_sync_single_for_device(d, addr, pkt_size, DMA_FROM_DEVICE);
return skb;
}
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 043850b..acf7105 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -2636,11 +2636,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring,
if (pci_dma_mapping_error(nic->pdev,
rxdp3->Buffer0_ptr))
goto pci_map_failed;
- } else
- pci_dma_sync_single_for_device(ring->pdev,
- (dma_addr_t)rxdp3->Buffer0_ptr,
- BUF0_LEN,
- PCI_DMA_FROMDEVICE);
+ }
rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN);
if (ring->rxd_mode == RXD_MODE_3B) {
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 98ec614..11e5229 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -3031,9 +3031,6 @@ static struct sk_buff *skge_rx_get(struct net_device *dev,
dma_unmap_addr(e, mapaddr),
len, PCI_DMA_FROMDEVICE);
skb_copy_from_linear_data(e->skb, skb->data, len);
- pci_dma_sync_single_for_device(skge->hw->pdev,
- dma_unmap_addr(e, mapaddr),
- len, PCI_DMA_FROMDEVICE);
skge_rx_reuse(e, skge->rx_buf_size);
} else {
struct sk_buff *nskb;
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 57339da..5f720b9 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -2422,8 +2422,6 @@ static struct sk_buff *receive_copy(struct sky2_port *sky2,
skb_copy_from_linear_data(re->skb, skb->data, length);
skb->ip_summed = re->skb->ip_summed;
skb->csum = re->skb->csum;
- pci_dma_sync_single_for_device(sky2->hw->pdev, re->data_addr,
- length, PCI_DMA_FROMDEVICE);
re->skb->ip_summed = CHECKSUM_NONE;
skb_put(skb, length);
}
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 8211b9a..b43d473 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -5002,7 +5002,6 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
skb_put(copy_skb, len);
pci_dma_sync_single_for_cpu(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE);
skb_copy_from_linear_data(skb, copy_skb->data, len);
- pci_dma_sync_single_for_device(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE);
/* We'll reuse the original ring buffer. */
skb = copy_skb;
diff --git a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c
index e3855ae..30fb6e8 100644
--- a/drivers/net/tokenring/olympic.c
+++ b/drivers/net/tokenring/olympic.c
@@ -837,9 +837,6 @@ static void olympic_rx(struct net_device *dev)
skb_copy_from_linear_data(olympic_priv->rx_ring_skb[rx_ring_last_received],
skb_put(skb,length - 4),
length - 4);
- pci_dma_sync_single_for_device(olympic_priv->pdev,
- le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer),
- olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ;
skb->protocol = tr_type_trans(skb,dev) ;
netif_rx(skb) ;
}
@@ -856,9 +853,6 @@ static void olympic_rx(struct net_device *dev)
skb_copy_from_linear_data(olympic_priv->rx_ring_skb[rx_ring_last_received],
skb_put(skb, cpy_length),
cpy_length);
- pci_dma_sync_single_for_device(olympic_priv->pdev,
- le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer),
- olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ;
} while (--i) ;
skb_trim(skb,skb->len-4) ;
skb->protocol = tr_type_trans(skb,dev);
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
index 15d878b..00d435d 100644
--- a/drivers/net/vxge/vxge-main.c
+++ b/drivers/net/vxge/vxge-main.c
@@ -323,9 +323,6 @@ vxge_rx_complete(struct vxge_ring *ring, struct sk_buff *skb, u16 vlan,
static inline void vxge_re_pre_post(void *dtr, struct vxge_ring *ring,
struct vxge_rx_priv *rx_priv)
{
- pci_dma_sync_single_for_device(ring->pdev,
- rx_priv->data_dma, rx_priv->data_size, PCI_DMA_FROMDEVICE);
-
vxge_hw_ring_rxd_1b_set(dtr, rx_priv->data_dma, rx_priv->data_size);
vxge_hw_ring_rxd_pre_post(ring->handle, dtr);
}
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c
index c33934a..11839be 100644
--- a/drivers/net/wireless/b43legacy/dma.c
+++ b/drivers/net/wireless/b43legacy/dma.c
@@ -433,17 +433,6 @@ void sync_descbuffer_for_cpu(struct b43legacy_dmaring *ring,
}
static inline
-void sync_descbuffer_for_device(struct b43legacy_dmaring *ring,
- dma_addr_t addr,
- size_t len)
-{
- B43legacy_WARN_ON(ring->tx);
-
- dma_sync_single_for_device(ring->dev->dev->dma_dev,
- addr, len, DMA_FROM_DEVICE);
-}
-
-static inline
void free_descriptor_buffer(struct b43legacy_dmaring *ring,
struct b43legacy_dmadesc_meta *meta,
int irq_context)
@@ -1556,8 +1545,6 @@ static void dma_rx(struct b43legacy_dmaring *ring,
}
b43legacy_handle_hwtxstatus(ring->dev, hw);
/* recycle the descriptor buffer. */
- sync_descbuffer_for_device(ring, meta->dmaaddr,
- ring->rx_buffersize);
return;
}
@@ -1573,8 +1560,6 @@ static void dma_rx(struct b43legacy_dmaring *ring,
} while (len == 0 && i++ < 5);
if (unlikely(len == 0)) {
/* recycle the descriptor buffer. */
- sync_descbuffer_for_device(ring, meta->dmaaddr,
- ring->rx_buffersize);
goto drop;
}
}
@@ -1590,8 +1575,6 @@ static void dma_rx(struct b43legacy_dmaring *ring,
while (1) {
desc = ops->idx2desc(ring, *slot, &meta);
/* recycle the descriptor buffer. */
- sync_descbuffer_for_device(ring, meta->dmaaddr,
- ring->rx_buffersize);
*slot = next_slot(ring, *slot);
cnt++;
tmp -= ring->rx_buffersize;
@@ -1609,8 +1592,6 @@ static void dma_rx(struct b43legacy_dmaring *ring,
if (unlikely(err)) {
b43legacydbg(ring->dev->wl, "DMA RX: setup_rx_descbuffer()"
" failed\n");
- sync_descbuffer_for_device(ring, dmaaddr,
- ring->rx_buffersize);
goto drop;
}
--
1.7.5.4
------------------------------------------------------------------------------
All of the data generated in your IT infrastructure is seriously valuable.
Why? It contains a definitive record of application performance, security
threats, fraudulent activity, and more. Splunk takes this data and makes
sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-d2d-c2
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel® Ethernet, visit http://communities.intel.com/community/wired
^ permalink raw reply related
* Re: [RFC 43/72] a2065/ariadne: Move the a2065/ariadne drivers
From: Jeff Kirsher @ 2011-07-11 0:48 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: davem@davemloft.net, netdev@vger.kernel.org
In-Reply-To: <CAMuHMdVHRNk4arc75QKrzDmHYE+86NixPk6v9uGwOAPkUTCgJw@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2439 bytes --]
On Sun, 2011-07-10 at 12:34 -0700, Geert Uytterhoeven wrote:
> On Sat, Jul 9, 2011 at 16:30, Jeff Kirsher
> <jeffrey.t.kirsher@intel.com> wrote:
> > On Tue, 2011-06-28 at 13:33 -0700, Geert Uytterhoeven wrote:
> >> And (in some other patch) 82596.c is an Intel driver, not a
> Motorola driver.
> >
> > 82596.c is not an Intel driver, it is an Intel part. The driver was
>
> Sorry, I meant "driver for an Intel part".
>
> > written and support by someone other than Intel. I am looking at
> how to
>
> Sure. But I'm strongly against classifying drivers based on who wrote
> them ;-)
I agree to some extent, because if that were the case, we would have a
donald_becker/ directory for several of the drivers. :)
Here is one of the problem's I keep running into and there is no simple
answer. While most of the drivers can be grouped together by the
hardware they use, that does not work "logically" for every driver.
In addition, if vendor 'A' makes a part and vendor 'B' uses same part in
a device/system/NIC and vendor 'B' creates the driver, supports the
driver and maintains the driver. Should the part be categorized under
vendor 'A'? IMHO, I think it should be categorized as a vendor 'B'
driver.
I started this work with the idea of trying to organize the drivers in
the same way that the drivers were to be in the Kconfig, which tended to
be drivers/net/ethernet/<manufacturer>.
One of the problems that arise in this organization is what do we do
when vendor A is bought by vendor B, and vendor B takes on the support
of all the old vendor A parts/drivers?
So I am open to suggestions. The process I have using to organize the
drivers has been to group drivers that use common libraries and/or code
first, then group by either manufacturer, maintainer, or common
platform.
I would like to keep the lasi_82506.c, sni_82596.c, 82506.c and similar
drivers out of the intel/ directory because we would not be supporting
the drivers and they are not similar to our drivers that we do support
that would be in the intel/ directory.
Again, I open to suggestions on how to best organize these types of
drivers. Maybe create a misc/ or <bus_type>/ for these types of
drivers?
>
> > better organize the 82596.c, lasi_82596.c, lib82596.c, and
> sni_82596.c
> > which all use an Intel Ethernet chip but were written and supported
> by
> > someone other than Intel.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 490 bytes --]
^ permalink raw reply
* Re: [RFC 43/72] a2065/ariadne: Move the a2065/ariadne drivers
From: Christoph Hellwig @ 2011-07-10 19:56 UTC (permalink / raw)
To: Jeff Kirsher
Cc: Geert Uytterhoeven, davem@davemloft.net, netdev@vger.kernel.org
In-Reply-To: <1310221836.26989.11.camel@jtkirshe-mobl>
On Sat, Jul 09, 2011 at 07:30:26AM -0700, Jeff Kirsher wrote:
> 82596.c is not an Intel driver, it is an Intel part. The driver was
> written and support by someone other than Intel.
Which doesn't matter at all.
^ permalink raw reply
* Re: [RFC 43/72] a2065/ariadne: Move the a2065/ariadne drivers
From: Geert Uytterhoeven @ 2011-07-10 19:34 UTC (permalink / raw)
To: jeffrey.t.kirsher; +Cc: davem@davemloft.net, netdev@vger.kernel.org
In-Reply-To: <1310221836.26989.11.camel@jtkirshe-mobl>
On Sat, Jul 9, 2011 at 16:30, Jeff Kirsher <jeffrey.t.kirsher@intel.com> wrote:
> On Tue, 2011-06-28 at 13:33 -0700, Geert Uytterhoeven wrote:
>> And (in some other patch) 82596.c is an Intel driver, not a Motorola driver.
>
> 82596.c is not an Intel driver, it is an Intel part. The driver was
Sorry, I meant "driver for an Intel part".
> written and support by someone other than Intel. I am looking at how to
Sure. But I'm strongly against classifying drivers based on who wrote them ;-)
> better organize the 82596.c, lasi_82596.c, lib82596.c, and sni_82596.c
> which all use an Intel Ethernet chip but were written and supported by
> someone other than Intel.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: ipv4: Simplify ARP hash function.
From: David Miller @ 2011-07-10 19:07 UTC (permalink / raw)
To: roland; +Cc: johnwheffner, mj, netdev
In-Reply-To: <CAL1RGDUzN_B0of0Ly6PxxaHM+A+E_1ZA0NTcC6jMmcrcoy0DxQ@mail.gmail.com>
From: Roland Dreier <roland@purestorage.com>
Date: Fri, 8 Jul 2011 16:11:00 -0700
> Maybe * of hash key with a random odd value is good enough?
Yes, from what I've read over the past few days it should
be. More precisely:
(key * hash_rnd) >> (32 - hash_table_size_log2)
where "hash_rnd" is odd.
The reason we want the top bits is because multiplies intrinsically
work such that bits in the inputs can only effect the same or higher
bits in the result.
^ permalink raw reply
* Re: [PATCH] slip: fix wrong SLIP6 ifdef-endif placing
From: Matvejchikov Ilya @ 2011-07-10 18:49 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20110710.113741.2147626275846755476.davem@davemloft.net>
SLIP6 have nothing to do with CSLIP so placing a block of
SLIP6-related code within a CSLIP ifdef-endif block is incorrect.
Signed-off-by: Ilya Matvejchikov <matvejchikov@gmail.com>
---
drivers/net/slip.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/slip.c b/drivers/net/slip.c
index 8ec1a9a..2f110fb 100644
--- a/drivers/net/slip.c
+++ b/drivers/net/slip.c
@@ -182,11 +182,11 @@ static int sl_alloc_bufs(struct slip *sl, int mtu)
#ifdef SL_INCLUDE_CSLIP
cbuff = xchg(&sl->cbuff, cbuff);
slcomp = xchg(&sl->slcomp, slcomp);
+#endif
#ifdef CONFIG_SLIP_MODE_SLIP6
sl->xdata = 0;
sl->xbits = 0;
#endif
-#endif
spin_unlock_bh(&sl->lock);
err = 0;
--
1.7.4.1
^ permalink raw reply related
* irlap_frame.c: Duplicate set?
From: Joe Perches @ 2011-07-10 18:43 UTC (permalink / raw)
To: Samuel Ortiz; +Cc: netdev
frame->caddr is consecutively set to multiple values.
The first set can probably be removed.
net/irda/irlap_frame.c
[...]
void irlap_send_rd_frame(struct irlap_cb *self)
{
struct sk_buff *tx_skb;
struct rd_frame *frame;
tx_skb = alloc_skb(sizeof(struct rd_frame), GFP_ATOMIC);
if (!tx_skb)
return;
frame = (struct rd_frame *)skb_put(tx_skb, 2);
frame->caddr = self->caddr;
frame->caddr = RD_RSP | PF_BIT;
irlap_queue_xmit(self, tx_skb);
}
^ permalink raw reply
* Re: [PATCH] slip: fix wrong SLIP6 ifdef-endif placing
From: David Miller @ 2011-07-10 18:37 UTC (permalink / raw)
To: matvejchikov; +Cc: netdev
In-Reply-To: <CAKh5nabf9OBG7yb5r=v0bhJLjNJgVrw-hVx9quJ9cwcOXSva=Q@mail.gmail.com>
From: Matvejchikov Ilya <matvejchikov@gmail.com>
Date: Sun, 10 Jul 2011 22:32:55 +0400
> SLIP6 have nothing to do with CSLIP so placing a block of
> SLIP6-related code within a CSLIP ifdef-endif block is incorrect.
>
> Signed-off-by: Ilya Matvejchikov <matvejchikov@gmail.com>
...
> @@ -194,8 +194,7 @@ static int sl_alloc_bufs(struct slip *sl, int mtu)
> err_exit:
> #ifdef SL_INCLUDE_CSLIP
> kfree(cbuff);
> - if (slcomp)
> - slhc_free(slcomp);
> + slhc_free(slcomp);
> #endif
The change in this hunk has nothing to do with what you
claim to be doing in your commit message.
Don't mix unrelated changes together.
^ permalink raw reply
* [PATCH] slip: fix wrong SLIP6 ifdef-endif placing
From: Matvejchikov Ilya @ 2011-07-10 18:32 UTC (permalink / raw)
To: netdev
SLIP6 have nothing to do with CSLIP so placing a block of
SLIP6-related code within a CSLIP ifdef-endif block is incorrect.
Signed-off-by: Ilya Matvejchikov <matvejchikov@gmail.com>
---
drivers/net/slip.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/slip.c b/drivers/net/slip.c
index 8ec1a9a..1ce6e08 100644
--- a/drivers/net/slip.c
+++ b/drivers/net/slip.c
@@ -182,11 +182,11 @@ static int sl_alloc_bufs(struct slip *sl, int mtu)
#ifdef SL_INCLUDE_CSLIP
cbuff = xchg(&sl->cbuff, cbuff);
slcomp = xchg(&sl->slcomp, slcomp);
+#endif
#ifdef CONFIG_SLIP_MODE_SLIP6
sl->xdata = 0;
sl->xbits = 0;
#endif
-#endif
spin_unlock_bh(&sl->lock);
err = 0;
@@ -194,8 +194,7 @@ static int sl_alloc_bufs(struct slip *sl, int mtu)
err_exit:
#ifdef SL_INCLUDE_CSLIP
kfree(cbuff);
- if (slcomp)
- slhc_free(slcomp);
+ slhc_free(slcomp);
#endif
kfree(xbuff);
kfree(rbuff);
--
1.7.4.1
^ permalink raw reply related
* Re: [PATCH] bridge: mask forwarding of IEEE 802 local multicast groups
From: Nick Carter @ 2011-07-10 16:04 UTC (permalink / raw)
To: netdev, Michał Mirosław, David Lamparter,
Stephen Hemminger; +Cc: davem
In-Reply-To: <BANLkTi=jnxBu6WzAOTxHD+e_O1qYKE2m=g@mail.gmail.com>
Updated diffs so they apply to net-next (Original diffs were based off 2.6.38).
Any chance of getting these diffs applied? The default behaviour of
the bridge code is unchanged. They solve the problem of
authenticating a virtual 802.1x supplicant machine against an external
802.1X authenticator. It is also a general solution that allows the
forwarding of any combination of the IEEE 802 local multicast groups.
Signed-off-by: Nick Carter <ncarter100@gmail.com>
Reviewed-by: David Lamparter <equinox@diac24.net>
net/bridge/br_device.c | 1 +
net/bridge/br_input.c | 3 +++
net/bridge/br_private.h | 8 ++++++++
net/bridge/br_sysfs_br.c | 23 +++++++++++++++++++++++
4 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 32b8f9f..573ed8c 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -366,6 +366,7 @@ void br_dev_setup(struct net_device *dev)
br->bridge_hello_time = br->hello_time = 2 * HZ;
br->bridge_forward_delay = br->forward_delay = 15 * HZ;
br->ageing_time = 300 * HZ;
+ br->group_fwd_mask = 0;
br_netfilter_rtable_init(br);
br_stp_timer_init(br);
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index f06ee39..3bee262 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -170,6 +170,9 @@ rx_handler_result_t br_handle_frame(struct sk_buff **pskb)
if (p->br->stp_enabled == BR_NO_STP && dest[5] == 0)
goto forward;
+ if (p->br->group_fwd_mask & (1 << dest[5]))
+ goto forward;
+
if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev,
NULL, br_handle_local_finish)) {
return RX_HANDLER_CONSUMED; /* consumed by filter */
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 54578f2..413fcec 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -244,6 +244,14 @@ struct net_bridge
struct timer_list multicast_query_timer;
#endif
+ /* Each bit used to match the least significant nibble of the
+ * IEEE 802.1D group address.
+ * 01-80-C2-00-00-00 bit 0
+ * ..
+ * 01-80-C2-00-00-0F bit 15
+ */
+ u16 group_fwd_mask;
+
struct timer_list hello_timer;
struct timer_list tcn_timer;
struct timer_list topology_change_timer;
diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
index 68b893e..d77f681 100644
--- a/net/bridge/br_sysfs_br.c
+++ b/net/bridge/br_sysfs_br.c
@@ -646,6 +646,28 @@ static DEVICE_ATTR(nf_call_arptables, S_IRUGO | S_IWUSR,
show_nf_call_arptables, store_nf_call_arptables);
#endif
+static ssize_t show_group_fwd_mask(struct device *d,
+ struct device_attribute *attr, char *buf)
+{
+ struct net_bridge *br = to_bridge(d);
+ return sprintf(buf, "%d\n", br->group_fwd_mask);
+}
+
+static int set_group_fwd_mask(struct net_bridge *br, unsigned long val)
+{
+ br->group_fwd_mask = (u16)val;
+ return 0;
+}
+
+static ssize_t store_group_fwd_mask(struct device *d,
+ struct device_attribute *attr,
+ const char *buf, size_t len)
+{
+ return store_bridge_parm(d, buf, len, set_group_fwd_mask);
+}
+static DEVICE_ATTR(group_fwd_mask, S_IRUGO | S_IWUSR, show_group_fwd_mask,
+ store_group_fwd_mask);
+
static struct attribute *bridge_attrs[] = {
&dev_attr_forward_delay.attr,
&dev_attr_hello_time.attr,
@@ -665,6 +687,7 @@ static struct attribute *bridge_attrs[] = {
&dev_attr_gc_timer.attr,
&dev_attr_group_addr.attr,
&dev_attr_flush.attr,
+ &dev_attr_group_fwd_mask.attr,
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
&dev_attr_multicast_router.attr,
&dev_attr_multicast_snooping.attr,
On 1 July 2011 22:21, Nick Carter <ncarter100@gmail.com> wrote:
> Introduce sysfs ../bridge/group_fwd_mask attribute so users can
> configure which group mac addresses are forwarded.
>
> These diffs do not change the default behaviour of bridge.ko. By
> changing the group_fwd_mask value users can select any combination of
> the 01-80-C2-00-00-00 - 01-80-C2-00-00-0F addresses to be forwarded.
>
> Signed-off-by: Nick Carter <ncarter100@gmail.com>
>
> diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
> index d9d1e2b..bb25e49 100644
> --- a/net/bridge/br_if.c
> +++ b/net/bridge/br_if.c
> @@ -214,6 +214,7 @@ static struct net_device *new_bridge_dev(struct
> net *net, const char *name)
> br->topology_change = 0;
> br->topology_change_detected = 0;
> br->ageing_time = 300 * HZ;
> + br->group_fwd_mask = 0;
>
> br_netfilter_rtable_init(br);
>
> diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
> index 90e985b..80b94f4 100644
> --- a/net/bridge/br_input.c
> +++ b/net/bridge/br_input.c
> @@ -166,6 +166,9 @@ struct sk_buff *br_handle_frame(struct sk_buff *skb)
> if (p->br->stp_enabled == BR_NO_STP && dest[5] == 0)
> goto forward;
>
> + if (p->br->group_fwd_mask & (1 << dest[5]))
> + goto forward;
> +
> if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev,
> NULL, br_handle_local_finish))
> return NULL; /* frame consumed by filter */
> diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
> index 4e1b620..d5aa164 100644
> --- a/net/bridge/br_private.h
> +++ b/net/bridge/br_private.h
> @@ -244,6 +244,13 @@ struct net_bridge
> struct timer_list multicast_query_timer;
> #endif
>
> + /* Each bit used to match the LSB of the IEEE 802.1D group address
> + * 01-80-C2-00-00-00 bit 0
> + * ..
> + * 01-80-C2-00-00-0F bit 15
> + */
> + u16 group_fwd_mask;
> +
> struct timer_list hello_timer;
> struct timer_list tcn_timer;
> struct timer_list topology_change_timer;
> diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
> index 5c1e555..f3cced5 100644
> --- a/net/bridge/br_sysfs_br.c
> +++ b/net/bridge/br_sysfs_br.c
> @@ -679,6 +679,28 @@ static DEVICE_ATTR(nf_call_arptables, S_IRUGO | S_IWUSR,
> show_nf_call_arptables, store_nf_call_arptables);
> #endif
>
> +static ssize_t show_group_fwd_mask(struct device *d, struct
> device_attribute *attr,
> + char *buf)
> +{
> + struct net_bridge *br = to_bridge(d);
> + return sprintf(buf, "%d\n", br->group_fwd_mask);
> +}
> +
> +static int set_group_fwd_mask(struct net_bridge *br, unsigned long val)
> +{
> + br->group_fwd_mask = (u16)val;
> + return 0;
> +}
> +
> +static ssize_t store_group_fwd_mask(struct device *d,
> + struct device_attribute *attr, const char *buf,
> + size_t len)
> +{
> + return store_bridge_parm(d, buf, len, set_group_fwd_mask);
> +}
> +static DEVICE_ATTR(group_fwd_mask, S_IRUGO | S_IWUSR, show_group_fwd_mask,
> + store_group_fwd_mask);
> +
> static struct attribute *bridge_attrs[] = {
> &dev_attr_forward_delay.attr,
> &dev_attr_hello_time.attr,
> @@ -698,6 +720,7 @@ static struct attribute *bridge_attrs[] = {
> &dev_attr_gc_timer.attr,
> &dev_attr_group_addr.attr,
> &dev_attr_flush.attr,
> + &dev_attr_group_fwd_mask.attr,
> #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
> &dev_attr_multicast_router.attr,
> &dev_attr_multicast_snooping.attr,
>
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox