From: Jon Mason <jdmason@us.ibm.com>
To: Francois Romieu <romieu@fr.zoreil.com>
Cc: netdev@oss.sgi.com
Subject: Re: [PATCH 2/3] r8169: code clean-up
Date: Sun, 20 Feb 2005 22:54:23 -0600 [thread overview]
Message-ID: <200502202254.23511.jdmason@us.ibm.com> (raw)
In-Reply-To: <20050220233405.GA14268@electric-eye.fr.zoreil.com>
On Sunday 20 February 2005 05:34 pm, Francois Romieu wrote:
[...]
> > True, but this problem existed before I made the jumbo frames changes. The
>
> AFAIKS, if the rx_copybreak fails, be it because the packet is too big or
> because the allocation failed, the current skb is sent to the upper layers.
You are correct, I misunderstood the error path of the previous rx_copy routine.
> > static inline int rtl8169_rx_copy(struct sk_buff **sk_buff, int pkt_size,
> > struct RxDesc *desc, struct rtl8169_private *tp)
> > {
> > u32 status = le32_to_cpu(desc->opts1);
> >
> > if ((pkt_size > rx_copybreak) &&
> > ((status & FirstFrag) && (status & LastFrag)))
> > return -1;
> >
> > if (status & FirstFrag) {
> > struct sk_buff *skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN);
> > u32 len = (pkt_size > rx_copybreak) ? tp->desc_part : pkt_size;
> >
> > if (skb) {
> > skb_reserve(skb, NET_IP_ALIGN);
> > memcpy(skb->data, sk_buff[0]->tail, len);
> > skb_put(skb, len);
> > } else {
> > printk(KERN_INFO "no rx skb allocated\n");
> > if (pkt_size <= rx_copybreak)
> > return -1;
> > }
> >
> > tp->new_skb = skb;
> > }
> >
> > Is this acceptable?
>
> I'll think more until I can figure I got the whole picture (only copy the
> first frament ?). I would have expected something like the mess below:
>
> static int rtl8169_rx_copy(struct sk_buff **sk_buff, int pkt_size,
> struct RxDesc *desc, struct rtl8169_private *tp)
> {
> u32 status = le32_to_cpu(desc->opts1);
> struct sk_buff *skb;
> int ret = -1;
>
> if ((pkt_size > rx_copybreak) && (status & FirstFrag) &&
> (status & LastFrag)) {
> goto out;
> }
>
> if (pkt_size < rx_copybreak) {
> skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN);
> if (!skb)
> goto out;
> skb_reserve(skb, NET_IP_ALIGN);
> } else if (status & FirstFrag)
> skb = tp->new_skb = sk_buff[0];
>
> if ((pkt_size < rx_copybreak) || !(status & FirstFrag)) {
> memcpy(skb->data, sk_buff[0]->tail, pkt_size);
> rtl8169_return_to_asic(desc, tp->rx_buf_sz);
> *sk_buff = skb;
> ret = 0;
> }
>
> skb_put(skb, pkt_size);
>
> out:
> return ret;
> }
>
> At this point I'd expect "How do you handle rtl8169_rx_copy() return ?"
> (or "yuck").
My main problem with the above patch is that is assumes that there will be a maximum of 2 descriptors per jumbo frame (which isn't the case). This might have been caused by my incomplete patch given above. This is what I currently have:
static inline int rtl8169_rx_copy(struct sk_buff **sk_buff, int pkt_size,
struct RxDesc *desc, struct rtl8169_private *tp)
{
u32 status = le32_to_cpu(desc->opts1);
if ((pkt_size > rx_copybreak) &&
((status & FirstFrag) && (status & LastFrag)))
return -1;
if (status & FirstFrag) {
u32 len = (pkt_size > rx_copybreak) ? tp->desc_part : pkt_size;
struct sk_buff *skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN);
if (skb) {
skb_reserve(skb, NET_IP_ALIGN);
memcpy(skb->data, sk_buff[0]->tail, len);
skb_put(skb, len);
} else {
printk(KERN_INFO "no rx skb allocated\n");
if (pkt_size <= rx_copybreak)
return -1;
}
tp->new_skb = skb;
}
if (!(status & FirstFrag) && !(status & LastFrag) && tp->new_skb) {
memcpy(tp->new_skb->tail, sk_buff[0]->tail, tp->desc_part);
skb_put(tp->new_skb, tp->desc_part);
}
if (status & LastFrag) {
if (pkt_size > rx_copybreak && tp->new_skb) {
memcpy(tp->new_skb->tail, sk_buff[0]->tail,
pkt_size - tp->new_skb->len);
skb_put(tp->new_skb, pkt_size - tp->new_skb->len);
}
*sk_buff = tp->new_skb;
}
rtl8169_return_to_asic(desc, tp->rx_buf_sz);
return 0;
}
> [...]
> > If I am still not making sense, I can be more verbose.
>
> Enlight me with the code, just to be sure.
Working (but still hackish) patch:
--- drivers/net/r8169.c.0220 2005-02-20 22:45:07.000000000 -0600
+++ drivers/net/r8169.c 2005-02-20 22:43:27.000000000 -0600
@@ -1663,7 +1663,8 @@ static void rtl8169_free_rx_skb(struct r
{
struct pci_dev *pdev = tp->pci_dev;
- pci_unmap_single(pdev, le64_to_cpu(desc->addr), tp->rx_buf_sz,
+ //pci_unmap_single(pdev, le64_to_cpu(desc->addr), tp->rx_buf_sz,
+ pci_unmap_single(pdev, le64_to_cpu(desc->addr), tp->desc_part+ETH_HLEN,
PCI_DMA_FROMDEVICE);
dev_kfree_skb(*sk_buff);
*sk_buff = NULL;
@@ -1694,14 +1695,14 @@ static int rtl8169_alloc_rx_skb(struct r
dma_addr_t mapping;
int ret = 0;
- skb = dev_alloc_skb(rx_buf_sz + NET_IP_ALIGN);
+ skb = dev_alloc_skb(tp->desc_part + ETH_HLEN + NET_IP_ALIGN);
if (!skb)
goto err_out;
skb_reserve(skb, NET_IP_ALIGN);
*sk_buff = skb;
- mapping = pci_map_single(tp->pci_dev, skb->tail, rx_buf_sz,
+ mapping = pci_map_single(tp->pci_dev, skb->tail, tp->desc_part+ETH_HLEN,
PCI_DMA_FROMDEVICE);
rtl8169_give_to_asic(desc, mapping, rx_buf_sz);
@@ -2225,7 +2226,7 @@ rtl8169_rx_interrupt(struct net_device *
rtl8169_rx_csum(skb, desc);
pci_dma_sync_single_for_cpu(tp->pci_dev,
- le64_to_cpu(desc->addr), tp->rx_buf_sz,
+ le64_to_cpu(desc->addr), tp->desc_part+ETH_HLEN,
PCI_DMA_FROMDEVICE);
if (rtl8169_rx_copy(&skb, pkt_size, desc, tp)) {
@@ -2235,7 +2236,7 @@ rtl8169_rx_interrupt(struct net_device *
}
pci_action(tp->pci_dev, le64_to_cpu(desc->addr),
- tp->rx_buf_sz, PCI_DMA_FROMDEVICE);
+ tp->desc_part+ETH_HLEN, PCI_DMA_FROMDEVICE);
if (skb && (status & LastFrag)) {
skb->dev = dev;
A more complete patch to follow shortly (as I want to try and fix my tabs problem).
next prev parent reply other threads:[~2005-02-21 4:54 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-02-17 0:23 [PATCH 2/3] r8169: code clean-up Jon Mason
2005-02-17 23:28 ` Francois Romieu
2005-02-18 4:00 ` Jon Mason
2005-02-20 17:52 ` Richard Dawe
2005-02-20 18:14 ` Jon Mason
2005-02-21 0:28 ` Francois Romieu
2005-02-21 3:40 ` Jon Mason
[not found] ` <200502181918.07859.jdmason@us.ibm.com>
[not found] ` <20050219104640.GA31035@electric-eye.fr.zoreil.com>
2005-02-19 17:47 ` Jon Mason
2005-02-19 22:30 ` Francois Romieu
2005-02-20 18:04 ` Jon Mason
2005-02-20 23:34 ` Francois Romieu
2005-02-21 4:54 ` Jon Mason [this message]
2005-02-21 8:16 ` Francois Romieu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200502202254.23511.jdmason@us.ibm.com \
--to=jdmason@us.ibm.com \
--cc=netdev@oss.sgi.com \
--cc=romieu@fr.zoreil.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.