* Re: [PATCH 1/9] mm: add a "struct subpage" type containing a page, offset and length
From: Christoph Hellwig @ 2011-10-10 15:55 UTC (permalink / raw)
To: Ian Campbell; +Cc: netdev, linux-mm
In-Reply-To: <1318245101-16890-1-git-send-email-ian.campbell@citrix.com>
On Mon, Oct 10, 2011 at 12:11:33PM +0100, Ian Campbell wrote:
> A few network drivers currently use skb_frag_struct for this purpose but I have
> patches which add additional fields and semantics there which these other uses
> do not want.
>
> A structure for reference sub-page regions seems like a generally useful thing
> so do so instead of adding a network subsystem specific structure.
Subpage seems like a fairly bad name. page_frag would fit into the
scheme used in a few other places.
The brings back the discussion of unifying the various incarnations we
have of this (biovec, skb frag and there were a few more at times),
but IIRC one of the sticking points back then was that one offset
insistet in 32-bit offset/len and the other on 16-bit.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: e100 + VLANs?
From: Eric Dumazet @ 2011-10-10 15:50 UTC (permalink / raw)
To: David Lamparter; +Cc: Michael Tokarev, jeffrey.t.kirsher, netdev
In-Reply-To: <20111010152845.GC3260852@jupiter.n2.diac24.net>
Le lundi 10 octobre 2011 à 17:28 +0200, David Lamparter a écrit :
> Huh? The remote sends the ARP request to ff:f..f:ff, which has a VLAN
> tag in both dumps - but the packet sent from the e100 only has a tag in
> its own tcpdump... so it might pretty much wind up on the wire without a
> tag due to some TX bug...
>
I read the reverse from the mail.
But this is probably the reverse :
MAC address of partner : 00:1f:c6:ef:e5:1b (ASUSTek prefix)
MAC address of e100 : 00:90:27:30:6d:1c
^ permalink raw reply
* Re: e100 + VLANs?
From: David Lamparter @ 2011-10-10 15:28 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Lamparter, Michael Tokarev, jeffrey.t.kirsher, netdev
In-Reply-To: <1318260235.3227.5.camel@edumazet-HP-Compaq-6005-Pro-SFF-PC>
On Mon, Oct 10, 2011 at 05:23:55PM +0200, Eric Dumazet wrote:
> Le lundi 10 octobre 2011 à 17:13 +0200, David Lamparter a écrit :
> > On Mon, Oct 10, 2011 at 05:05:52PM +0200, Eric Dumazet wrote:
> > > > When pinging this NIC from another machine over VLAN5, I see
> > > > ARP packets coming to it, gets recognized and replies going
> > > > back, all on vlan 5. But on the other side, replies comes
> > > > WITHOUT a VLAN tag!
> > > >
> > > > From this NIC's point of view, capturing on whole ethX:
> > > >
> > > > 00:1f:c6:ef:e5:1b > ff:ff:ff:ff:ff:ff, ethertype 802.1Q (0x8100), length 60: vlan 5, p 0, ethertype ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 10.48.11.2 tell 10.48.11.1, length 42
> > > > 00:90:27:30:6d:1c > 00:1f:c6:ef:e5:1b, ethertype 802.1Q (0x8100), length 46: vlan 5, p 0, ethertype ARP, Ethernet (len 6), IPv4 (len 4), Reply 10.48.11.2 is-at 00:90:27:30:6d:1c, length 28
> > > >
> > > > From the partner point of view, also on whole ethX:
> > > >
> > > > 00:1f:c6:ef:e5:1b > ff:ff:ff:ff:ff:ff, ethertype 802.1Q (0x8100), length 46: vlan 5, p 0, ethertype ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 10.48.11.2 tell 10.48.11.1, length 28
> > > > 00:90:27:30:6d:1c > 00:1f:c6:ef:e5:1b, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Reply 10.48.11.2 is-at 00:90:27:30:6d:1c, length 46
> > > >
> > > > So, the tag gets eaten somewhere along the way... ;)
> >
> > Hmm. Looks like broken VLAN TX offload, but the driver doesn't even
> > implement VLAN offload. Maybe it's broken in its non-implementation...
> >
> > Your "partner" is a known-good setup and can be assumed to be working
> > correctly? This is over a crossover cable, no evil switches involved?
> >
> > > > And I can't really recreate the situation which I had - I know
> > > > some packets were flowing, so at least ARP worked. Now it
> > > > does not work anymore.
> > >
> > > What the 'partner' setup looks like ?
> > >
> > > ip link
> > > ip addr
> > > ip ro
> >
> > 'local' setup too please :)
>
> But here, the remote cleary sends an answer without VLAN tag ;)
Huh? The remote sends the ARP request to ff:f..f:ff, which has a VLAN
tag in both dumps - but the packet sent from the e100 only has a tag in
its own tcpdump... so it might pretty much wind up on the wire without a
tag due to some TX bug...
-David
^ permalink raw reply
* Re: loopback IP alias breaks tftp?
From: Olaf van der Spek @ 2011-10-10 15:25 UTC (permalink / raw)
To: Eric Dumazet
Cc: Josh Boyer, Joel Sing, Julian Anastasov, netdev, francis.souyri
In-Reply-To: <1318260126.3227.4.camel@edumazet-HP-Compaq-6005-Pro-SFF-PC>
On Mon, Oct 10, 2011 at 5:22 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>> Isn't that a bad way to work around this issue?
>> It'd require you to duplicate your IP config for every daemon that
>> listens on UDP interfaces.
>> What about IP addresses that are added/deleted after the daemon is launchad?
>>
>> Olaf
>
> Thats a pretty common problem, even prior to discussed commit.
>
> If you take a look at common UDP daemons, they have to setup a listener
> for each IP address, OR use the correct API ( setsockopt(fd, IPPROTO_IP,
> &on, sizeof(on)) and handle IP_PKTINFO ancillary message)
Only the latter solution seems right.
Olaf
^ permalink raw reply
* Re: e100 + VLANs?
From: Eric Dumazet @ 2011-10-10 15:23 UTC (permalink / raw)
To: David Lamparter; +Cc: Michael Tokarev, jeffrey.t.kirsher, netdev
In-Reply-To: <20111010151343.GB3260852@jupiter.n2.diac24.net>
Le lundi 10 octobre 2011 à 17:13 +0200, David Lamparter a écrit :
> On Mon, Oct 10, 2011 at 05:05:52PM +0200, Eric Dumazet wrote:
> > > When pinging this NIC from another machine over VLAN5, I see
> > > ARP packets coming to it, gets recognized and replies going
> > > back, all on vlan 5. But on the other side, replies comes
> > > WITHOUT a VLAN tag!
> > >
> > > From this NIC's point of view, capturing on whole ethX:
> > >
> > > 00:1f:c6:ef:e5:1b > ff:ff:ff:ff:ff:ff, ethertype 802.1Q (0x8100), length 60: vlan 5, p 0, ethertype ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 10.48.11.2 tell 10.48.11.1, length 42
> > > 00:90:27:30:6d:1c > 00:1f:c6:ef:e5:1b, ethertype 802.1Q (0x8100), length 46: vlan 5, p 0, ethertype ARP, Ethernet (len 6), IPv4 (len 4), Reply 10.48.11.2 is-at 00:90:27:30:6d:1c, length 28
> > >
> > > From the partner point of view, also on whole ethX:
> > >
> > > 00:1f:c6:ef:e5:1b > ff:ff:ff:ff:ff:ff, ethertype 802.1Q (0x8100), length 46: vlan 5, p 0, ethertype ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 10.48.11.2 tell 10.48.11.1, length 28
> > > 00:90:27:30:6d:1c > 00:1f:c6:ef:e5:1b, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Reply 10.48.11.2 is-at 00:90:27:30:6d:1c, length 46
> > >
> > > So, the tag gets eaten somewhere along the way... ;)
>
> Hmm. Looks like broken VLAN TX offload, but the driver doesn't even
> implement VLAN offload. Maybe it's broken in its non-implementation...
>
> Your "partner" is a known-good setup and can be assumed to be working
> correctly? This is over a crossover cable, no evil switches involved?
>
> > > And I can't really recreate the situation which I had - I know
> > > some packets were flowing, so at least ARP worked. Now it
> > > does not work anymore.
> >
> > What the 'partner' setup looks like ?
> >
> > ip link
> > ip addr
> > ip ro
>
> 'local' setup too please :)
But here, the remote cleary sends an answer without VLAN tag ;)
Maybe its a tg3 (we had a buggy driver until very recent change), or
tcpdump is not up2date...
^ permalink raw reply
* Re: loopback IP alias breaks tftp?
From: Eric Dumazet @ 2011-10-10 15:22 UTC (permalink / raw)
To: Olaf van der Spek
Cc: Josh Boyer, Joel Sing, Julian Anastasov, netdev, francis.souyri
In-Reply-To: <CAGVGHmsF3JBqpqzKa_Fp6oOcVKX5BKgJUG=UJvPZcNgKiSsrRA@mail.gmail.com>
Le lundi 10 octobre 2011 à 17:15 +0200, Olaf van der Spek a écrit :
> > On Fri, Oct 07, 2011 at 02:23:21PM +0200, Eric Dumazet wrote:
> >> By the way, there is no need for tftp change :
> >>
> >> Just launch several tftpd instances, and bind each them to one
> >> particular IP.
> >>
> >> If started from xinetd.d :
>
> Isn't that a bad way to work around this issue?
> It'd require you to duplicate your IP config for every daemon that
> listens on UDP interfaces.
> What about IP addresses that are added/deleted after the daemon is launchad?
>
> Olaf
Thats a pretty common problem, even prior to discussed commit.
If you take a look at common UDP daemons, they have to setup a listener
for each IP address, OR use the correct API ( setsockopt(fd, IPPROTO_IP,
&on, sizeof(on)) and handle IP_PKTINFO ancillary message)
^ permalink raw reply
* Re: loopback IP alias breaks tftp?
From: Olaf van der Spek @ 2011-10-10 15:15 UTC (permalink / raw)
To: Josh Boyer
Cc: Eric Dumazet, Joel Sing, Julian Anastasov, netdev, francis.souyri
In-Reply-To: <20111010151058.GD1165@zod.bos.redhat.com>
> On Fri, Oct 07, 2011 at 02:23:21PM +0200, Eric Dumazet wrote:
>> By the way, there is no need for tftp change :
>>
>> Just launch several tftpd instances, and bind each them to one
>> particular IP.
>>
>> If started from xinetd.d :
Isn't that a bad way to work around this issue?
It'd require you to duplicate your IP config for every daemon that
listens on UDP interfaces.
What about IP addresses that are added/deleted after the daemon is launchad?
Olaf
^ permalink raw reply
* Re: [PATCH 9/9] net: add opaque struct around skb frag page
From: Ian Campbell @ 2011-10-10 15:13 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev@vger.kernel.org
In-Reply-To: <1318259375.3227.1.camel@edumazet-HP-Compaq-6005-Pro-SFF-PC>
On Mon, 2011-10-10 at 16:09 +0100, Eric Dumazet wrote:
> Le lundi 10 octobre 2011 à 12:11 +0100, Ian Campbell a écrit :
> > I've split this bit out of the skb frag destructor patch since it helps enforce
> > the use of the fragment API.
> >
> > Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
> > ---
> > include/linux/skbuff.h | 10 ++++++----
> > net/core/skbuff.c | 6 +++---
> > 2 files changed, 9 insertions(+), 7 deletions(-)
> >
> > diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
> > index ac6b05a..f881d75 100644
> > --- a/include/linux/skbuff.h
> > +++ b/include/linux/skbuff.h
> > @@ -135,7 +135,9 @@ struct sk_buff;
> > typedef struct skb_frag_struct skb_frag_t;
> >
> > struct skb_frag_struct {
> > - struct page *page;
> > + struct {
> > + struct page *p;
> > + } page;
>
> Oh well, why dont you rename page to something else, say frag_page ?
I looked at renaming this field and the impact was far larger than this
(already huge) set of series.
Keeping the name for the outer struct also has the nice property that
when the struct becomes something like:
struct {
struct page *p;
struct skb_frag_destructor *destr;
} page;
existing code which does
fraga->page = fragb->page
will carry the destructor along magically without needing modification.
Ian.
>
>
>
^ permalink raw reply
* Re: e100 + VLANs?
From: David Lamparter @ 2011-10-10 15:13 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Michael Tokarev, David Lamparter, jeffrey.t.kirsher, netdev
In-Reply-To: <1318259152.3227.0.camel@edumazet-HP-Compaq-6005-Pro-SFF-PC>
On Mon, Oct 10, 2011 at 05:05:52PM +0200, Eric Dumazet wrote:
> > When pinging this NIC from another machine over VLAN5, I see
> > ARP packets coming to it, gets recognized and replies going
> > back, all on vlan 5. But on the other side, replies comes
> > WITHOUT a VLAN tag!
> >
> > From this NIC's point of view, capturing on whole ethX:
> >
> > 00:1f:c6:ef:e5:1b > ff:ff:ff:ff:ff:ff, ethertype 802.1Q (0x8100), length 60: vlan 5, p 0, ethertype ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 10.48.11.2 tell 10.48.11.1, length 42
> > 00:90:27:30:6d:1c > 00:1f:c6:ef:e5:1b, ethertype 802.1Q (0x8100), length 46: vlan 5, p 0, ethertype ARP, Ethernet (len 6), IPv4 (len 4), Reply 10.48.11.2 is-at 00:90:27:30:6d:1c, length 28
> >
> > From the partner point of view, also on whole ethX:
> >
> > 00:1f:c6:ef:e5:1b > ff:ff:ff:ff:ff:ff, ethertype 802.1Q (0x8100), length 46: vlan 5, p 0, ethertype ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 10.48.11.2 tell 10.48.11.1, length 28
> > 00:90:27:30:6d:1c > 00:1f:c6:ef:e5:1b, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Reply 10.48.11.2 is-at 00:90:27:30:6d:1c, length 46
> >
> > So, the tag gets eaten somewhere along the way... ;)
Hmm. Looks like broken VLAN TX offload, but the driver doesn't even
implement VLAN offload. Maybe it's broken in its non-implementation...
Your "partner" is a known-good setup and can be assumed to be working
correctly? This is over a crossover cable, no evil switches involved?
> > And I can't really recreate the situation which I had - I know
> > some packets were flowing, so at least ARP worked. Now it
> > does not work anymore.
>
> What the 'partner' setup looks like ?
>
> ip link
> ip addr
> ip ro
'local' setup too please :)
-David
^ permalink raw reply
* Re: loopback IP alias breaks tftp?
From: Josh Boyer @ 2011-10-10 15:10 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Joel Sing, Julian Anastasov, netdev, francis.souyri
In-Reply-To: <1317990201.3207.15.camel@edumazet-HP-Compaq-6005-Pro-SFF-PC>
On Fri, Oct 07, 2011 at 02:23:21PM +0200, Eric Dumazet wrote:
> Le vendredi 07 octobre 2011 à 14:04 +0200, Eric Dumazet a écrit :
>
> > Its a completely different problem IMHO : You describe a tftp server
> > bug.
> >
> > Say your tftp server is multihomed with 3 different IPS :
> >
> > 192.168.20.21, 192.168.20.22, 192.168.20.23
> >
> > And tftp server listens to any address (UDP port 69) : 0.0.0.0:69
> >
> > When receiving a request on 192.168.20.22, it should use same source
> > address, not let the system chose a "random or whatever policy" one.
> >
> >
> >
> > So I would suggest to check/fix if TFTP server uses the correct socket
> > API to get both the client IP and its own IP in each UDP datagram
> >
> > -> setsockopt(fd, IPPROTO_IP, &on, sizeof(on))
>
> > This permits tftp server to use the same "struct in_pktinfo" for replies, forcing a correct source address.
> >
>
> By the way, there is no need for tftp change :
>
> Just launch several tftpd instances, and bind each them to one
> particular IP.
>
> If started from xinetd.d :
>
> $ cat /etc/xinetd.d/tftp1
> service tftp
> {
> socket_type = dgram
> protocol = udp
> wait = yes
> user = root
> server = /usr/sbin/in.tftpd
> server_args = -s /tftpboot
> disable = no
> bind = 192.168.20.21
> per_source = 11
> cps = 100 2
> flags = IPv4
> }
(I've CC'd the original bug reporter now.)
I did this locally and it still timed out. So the bind alone is not
enough to fix the problem. At least not on lo:0 127.0.0.2.
Changing the source address in the routing table as Joel suggested does
work around the problem.
So, in summary, either the TFTP server needs to be changed per your
original suggestion, or the routing table needs to be altered for every
alias? Is that correct?
josh
^ permalink raw reply
* Re: [PATCH 9/9] net: add opaque struct around skb frag page
From: Eric Dumazet @ 2011-10-10 15:09 UTC (permalink / raw)
To: Ian Campbell; +Cc: netdev
In-Reply-To: <1318245101-16890-9-git-send-email-ian.campbell@citrix.com>
Le lundi 10 octobre 2011 à 12:11 +0100, Ian Campbell a écrit :
> I've split this bit out of the skb frag destructor patch since it helps enforce
> the use of the fragment API.
>
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
> ---
> include/linux/skbuff.h | 10 ++++++----
> net/core/skbuff.c | 6 +++---
> 2 files changed, 9 insertions(+), 7 deletions(-)
>
> diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
> index ac6b05a..f881d75 100644
> --- a/include/linux/skbuff.h
> +++ b/include/linux/skbuff.h
> @@ -135,7 +135,9 @@ struct sk_buff;
> typedef struct skb_frag_struct skb_frag_t;
>
> struct skb_frag_struct {
> - struct page *page;
> + struct {
> + struct page *p;
> + } page;
Oh well, why dont you rename page to something else, say frag_page ?
^ permalink raw reply
* Re: e100 + VLANs?
From: Eric Dumazet @ 2011-10-10 15:05 UTC (permalink / raw)
To: Michael Tokarev; +Cc: David Lamparter, jeffrey.t.kirsher, netdev
In-Reply-To: <4E9307CB.4050704@msgid.tls.msk.ru>
Le lundi 10 octobre 2011 à 18:57 +0400, Michael Tokarev a écrit :
> 10.10.2011 14:19, David Lamparter wrote:
> > On Sat, Oct 08, 2011 at 11:34:40AM -0700, Jeff Kirsher wrote:
> >> On 10/08/2011 09:24 AM, Eric Dumazet wrote:
> >>> Le samedi 08 octobre 2011 à 14:08 +0400, Michael Tokarev a écrit :
> >>>>> Yesterday I tried to use 802.1Q VLAN tagging with an (oldish)
> >>>>> e100-driven network card, identified by lspci like this:
> >>>>>
> >>>>> 00:12.0 Ethernet controller: Intel Corporation 82557/8/9/0/1 Ethernet Pro 100 (rev 02)
> >>>>>
> >>>>> Just to discover that it does not quite work: packets of
> >>>>> size 1497+ bytes gets lost.
> > [...]
> >>> e100 driver seems VLAN enabled at a first glance.
> >> Eric is correct, that e100 does support VLANs.
> >>
> >> In addition to Eric's suggestion, can you also provide all the output of
> >> lspci -vvv for the network card?
> >
> > I'm opening the lore box here, but early e100 cards AFAIK have a
> > hardware limit at 1500 (+18 src/dst/proto) bytes. At least, Juniper's
> > JUNOS does not support full-sized .1Q on their e100 control plane
> > interfaces...
>
> Thank you all for the suggestions and feedback.
>
> The card may indeed be quite old, I don't know where it come from and
> when. Here's lspci -vvv for it:
>
> 00:12.0 Ethernet controller: Intel Corporation 82557/8/9/0/1 Ethernet Pro 100 (rev 02)
> Subsystem: Intel Corporation EtherExpress PRO/100B (TX)
> Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx-
> Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
> Latency: 66 (2000ns min, 14000ns max)
> Interrupt: pin A routed to IRQ 11
> Region 0: Memory at fe200000 (32-bit, prefetchable) [size=4K]
> Region 1: I/O ports at 2400 [size=32]
> Region 2: Memory at fc000000 (32-bit, non-prefetchable) [size=1M]
> [virtual] Expansion ROM at 30100000 [disabled] [size=1M]
> Kernel driver in use: e100
>
>
> I tried to set it up to talk to another machine in order to find
> out where the packets gets lost. But had another complication
> on the way: it does not "want" to work with 802.1Q VLANs anymore
> at all... ;)
>
> When pinging this NIC from another machine over VLAN5, I see
> ARP packets coming to it, gets recognized and replies going
> back, all on vlan 5. But on the other side, replies comes
> WITHOUT a VLAN tag!
>
> From this NIC's point of view, capturing on whole ethX:
>
> 00:1f:c6:ef:e5:1b > ff:ff:ff:ff:ff:ff, ethertype 802.1Q (0x8100), length 60: vlan 5, p 0, ethertype ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 10.48.11.2 tell 10.48.11.1, length 42
> 00:90:27:30:6d:1c > 00:1f:c6:ef:e5:1b, ethertype 802.1Q (0x8100), length 46: vlan 5, p 0, ethertype ARP, Ethernet (len 6), IPv4 (len 4), Reply 10.48.11.2 is-at 00:90:27:30:6d:1c, length 28
>
> From the partner point of view, also on whole ethX:
>
> 00:1f:c6:ef:e5:1b > ff:ff:ff:ff:ff:ff, ethertype 802.1Q (0x8100), length 46: vlan 5, p 0, ethertype ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 10.48.11.2 tell 10.48.11.1, length 28
> 00:90:27:30:6d:1c > 00:1f:c6:ef:e5:1b, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Reply 10.48.11.2 is-at 00:90:27:30:6d:1c, length 46
>
> So, the tag gets eaten somewhere along the way... ;)
>
> And I can't really recreate the situation which I had - I know
> some packets were flowing, so at least ARP worked. Now it
> does not work anymore.
What the 'partner' setup looks like ?
ip link
ip addr
ip ro
^ permalink raw reply
* Re: e100 + VLANs?
From: Michael Tokarev @ 2011-10-10 14:57 UTC (permalink / raw)
To: David Lamparter; +Cc: jeffrey.t.kirsher, Eric Dumazet, netdev
In-Reply-To: <20111010101954.GB2840382@jupiter.n2.diac24.net>
10.10.2011 14:19, David Lamparter wrote:
> On Sat, Oct 08, 2011 at 11:34:40AM -0700, Jeff Kirsher wrote:
>> On 10/08/2011 09:24 AM, Eric Dumazet wrote:
>>> Le samedi 08 octobre 2011 à 14:08 +0400, Michael Tokarev a écrit :
>>>>> Yesterday I tried to use 802.1Q VLAN tagging with an (oldish)
>>>>> e100-driven network card, identified by lspci like this:
>>>>>
>>>>> 00:12.0 Ethernet controller: Intel Corporation 82557/8/9/0/1 Ethernet Pro 100 (rev 02)
>>>>>
>>>>> Just to discover that it does not quite work: packets of
>>>>> size 1497+ bytes gets lost.
> [...]
>>> e100 driver seems VLAN enabled at a first glance.
>> Eric is correct, that e100 does support VLANs.
>>
>> In addition to Eric's suggestion, can you also provide all the output of
>> lspci -vvv for the network card?
>
> I'm opening the lore box here, but early e100 cards AFAIK have a
> hardware limit at 1500 (+18 src/dst/proto) bytes. At least, Juniper's
> JUNOS does not support full-sized .1Q on their e100 control plane
> interfaces...
Thank you all for the suggestions and feedback.
The card may indeed be quite old, I don't know where it come from and
when. Here's lspci -vvv for it:
00:12.0 Ethernet controller: Intel Corporation 82557/8/9/0/1 Ethernet Pro 100 (rev 02)
Subsystem: Intel Corporation EtherExpress PRO/100B (TX)
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx-
Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 66 (2000ns min, 14000ns max)
Interrupt: pin A routed to IRQ 11
Region 0: Memory at fe200000 (32-bit, prefetchable) [size=4K]
Region 1: I/O ports at 2400 [size=32]
Region 2: Memory at fc000000 (32-bit, non-prefetchable) [size=1M]
[virtual] Expansion ROM at 30100000 [disabled] [size=1M]
Kernel driver in use: e100
I tried to set it up to talk to another machine in order to find
out where the packets gets lost. But had another complication
on the way: it does not "want" to work with 802.1Q VLANs anymore
at all... ;)
When pinging this NIC from another machine over VLAN5, I see
ARP packets coming to it, gets recognized and replies going
back, all on vlan 5. But on the other side, replies comes
WITHOUT a VLAN tag!
From this NIC's point of view, capturing on whole ethX:
00:1f:c6:ef:e5:1b > ff:ff:ff:ff:ff:ff, ethertype 802.1Q (0x8100), length 60: vlan 5, p 0, ethertype ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 10.48.11.2 tell 10.48.11.1, length 42
00:90:27:30:6d:1c > 00:1f:c6:ef:e5:1b, ethertype 802.1Q (0x8100), length 46: vlan 5, p 0, ethertype ARP, Ethernet (len 6), IPv4 (len 4), Reply 10.48.11.2 is-at 00:90:27:30:6d:1c, length 28
From the partner point of view, also on whole ethX:
00:1f:c6:ef:e5:1b > ff:ff:ff:ff:ff:ff, ethertype 802.1Q (0x8100), length 46: vlan 5, p 0, ethertype ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 10.48.11.2 tell 10.48.11.1, length 28
00:90:27:30:6d:1c > 00:1f:c6:ef:e5:1b, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Reply 10.48.11.2 is-at 00:90:27:30:6d:1c, length 46
So, the tag gets eaten somewhere along the way... ;)
And I can't really recreate the situation which I had - I know
some packets were flowing, so at least ARP worked. Now it
does not work anymore.
Hmm.... ;)
Thank you!
/mjt
^ permalink raw reply
* Re: net/fec on i.MX28: failure after network cable unplug or device down
From: Lothar Waßmann @ 2011-10-10 13:52 UTC (permalink / raw)
To: Uwe Kleine-König; +Cc: netdev, Shawn Guo, Wolfram Sang
In-Reply-To: <20111010131705.GA25293@pengutronix.de>
[-- Attachment #1: message body and .signature --]
[-- Type: text/plain, Size: 846 bytes --]
Hi,
Uwe Kleine-König writes:
> Hello,
>
> I currently see the problem on two different i.MX28 based system
> (Freescale's mx28evk and a Karo TX28) that after unplugging and
> reconnection of the network cable or ifconfig down; ifconfig up; the
> network is dead. That means nothing is sent or received anymore.
>
I already solved this problem (and some others too), but wasn't able
to send any patch yet.
The FEC of the i.MX28 requires the ETHER_EN bit in the ECR to be set
for the MII interface to work. Resetting the interface upon shutdown
is required though, because otherwise the receiver will remain active
and use the stale DMA descriptors in memory to store received packets!
Furthermore the (R)MII mode must be configured correctly in the RCR
register.
The current state of my patch is appended for reference.
Lothar Waßmann
--
[-- Attachment #2: fec-cleanup --]
[-- Type: application/octet-stream, Size: 3610 bytes --]
Index: linux/drivers/net/fec.c
===================================================================
--- linux.orig/drivers/net/fec.c 2011-09-13 09:58:38.000000000 +0200
+++ linux/drivers/net/fec.c 2011-09-13 09:58:41.000000000 +0200
@@ -486,10 +486,16 @@
writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
}
+/* prevent the FEC from transmitting/receiving packets, but leave
+ * the MII interface active to detect link change
+ */
static void
fec_stop(struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
+ const struct platform_device_id *id_entry =
+ platform_get_device_id(fep->pdev);
+ u32 rmii_mode = readl(fep->hwp + FEC_R_CNTRL) & (1 << 8);
/* We cannot expect a graceful transmit stop without link !!! */
if (fep->link) {
@@ -504,8 +510,33 @@
udelay(10);
writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
+
+ if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) {
+ /* i.MX28 requires ETHER_EN enabled to be able to
+ * access the PHY registers and the RMII mode properly set to
+ * be able to detect link changes
+ */
+ writel(2, fep->hwp + FEC_ECNTRL);
+ writel(rmii_mode, fep->hwp + FEC_R_CNTRL);
+ }
}
+/* shutdown the FEC and the MII interface */
+static void
+fec_shutdown(struct net_device *ndev)
+{
+ struct fec_enet_private *fep = netdev_priv(ndev);
+
+ /* We cannot expect a graceful transmit stop without link !!! */
+ if (fep->link) {
+ writel(1, fep->hwp + FEC_X_CNTRL); /* Graceful transmit stop */
+ udelay(10);
+ if (!(readl(fep->hwp + FEC_IEVENT) & FEC_ENET_GRA))
+ printk("fec_stop : Graceful transmit stop did not complete !\n");
+ }
+
+ writel(0, fep->hwp + FEC_ECNTRL);
+}
static void
fec_timeout(struct net_device *ndev)
@@ -789,7 +820,7 @@
iap = (unsigned char *)FEC_FLASHMAC;
#else
if (pdata)
- memcpy(iap, pdata->mac, ETH_ALEN);
+ iap = (unsigned char *)&pdata->mac;
#endif
}
@@ -836,6 +867,8 @@
if (phy_dev->link) {
if (fep->full_duplex != phy_dev->duplex) {
fec_restart(ndev, phy_dev->duplex);
+ /* prevent unnecessary second fec_restart() below */
+ fep->link = phy_dev->link;
status_change = 1;
}
}
@@ -1052,8 +1085,6 @@
static void fec_enet_mii_remove(struct fec_enet_private *fep)
{
- if (fep->phy_dev)
- phy_disconnect(fep->phy_dev);
mdiobus_unregister(fep->mii_bus);
kfree(fep->mii_bus->irq);
mdiobus_free(fep->mii_bus);
@@ -1184,6 +1215,8 @@
fec_enet_open(struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
+ const struct platform_device_id *id_entry =
+ platform_get_device_id(fep->pdev);
int ret;
/* I should reset the ring buffers here, but I don't yet know
@@ -1214,7 +1247,7 @@
/* Don't know what to do yet. */
fep->opened = 0;
netif_stop_queue(ndev);
- fec_stop(ndev);
+ fec_shutdown(ndev);
if (fep->phy_dev) {
phy_stop(fep->phy_dev);
@@ -1518,7 +1551,7 @@
}
}
- fep->clk = clk_get(&pdev->dev, "fec_clk");
+ fep->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(fep->clk)) {
ret = PTR_ERR(fep->clk);
goto failed_clk;
@@ -1570,13 +1603,18 @@
struct net_device *ndev = platform_get_drvdata(pdev);
struct fec_enet_private *fep = netdev_priv(ndev);
struct resource *r;
+ int i;
- fec_stop(ndev);
+ unregister_netdev(ndev);
fec_enet_mii_remove(fep);
+ for (i = 0; i < 3; i++) {
+ int irq = platform_get_irq(pdev, i);
+ if (irq > 0)
+ free_irq(irq, ndev);
+ }
clk_disable(fep->clk);
clk_put(fep->clk);
iounmap(fep->hwp);
- unregister_netdev(ndev);
free_netdev(ndev);
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
[-- Attachment #3: message body text --]
[-- Type: text/plain, Size: 367 bytes --]
___________________________________________________________
Ka-Ro electronics GmbH | Pascalstraße 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Geschäftsführer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996
www.karo-electronics.de | info@karo-electronics.de
___________________________________________________________
^ permalink raw reply
* Re:await your response
From: Chang @ 2011-10-10 10:15 UTC (permalink / raw)
My name is Mr Young Chang, Head of operation Mevas Bank here in Hong Kong. I have a business proposal that i will like you to handle with me from my bank worth 19.7m USD
^ permalink raw reply
* net/fec on i.MX28: failure after network cable unplug or device down
From: Uwe Kleine-König @ 2011-10-10 13:17 UTC (permalink / raw)
To: netdev; +Cc: Shawn Guo, Wolfram Sang, Lothar Waßmann
Hello,
I currently see the problem on two different i.MX28 based system
(Freescale's mx28evk and a Karo TX28) that after unplugging and
reconnection of the network cable or ifconfig down; ifconfig up; the
network is dead. That means nothing is sent or received anymore.
ifconfig up dies with:
[ 32.120000] FEC: MDIO read timeout
[ 32.120000] eth0: could not attach to PHY
ifconfig: SIOCSIFFLAGS: Connection timed out
after unplugging the network cable I get:
[ 25.520000] PHY: 1:00 - Link is Down
[ 26.530000] FEC: MDIO read timeout
In both cases the mdio read operation doesn't fire the mii irq, though
the FEC_MII_DATA contains data that looks right and the interrupt
register (FEC_IEVENT) has the mii bit set and according to the mask
register (FEC_IMASK) the irq isn't masked.
When commenting out
writel(1, fep->hwp + FEC_ECNTRL);
(i.e. don't reset the network unit) in fec_stop it works (but Wolfram
seems to remember that doing so breaks e.g. i.MX35. We have not checked
yet).
Strange enough with the reset commented out in fec_stop, fec_restart
resets the fec (when the cable is reconnected) but without breaking it.
I tried to restore more registers in fec_stop (most notably FEC_R_CNTRL
that has some mii fields) but without success.
Do you see this problem, too? Maybe do you have an idea to fix it?
Currently I use the following patch:
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 5b631fe..8c1330f 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -458,6 +458,8 @@ static void
fec_stop(struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
+ const struct platform_device_id *id_entry =
+ platform_get_device_id(fep->pdev);
/* We cannot expect a graceful transmit stop without link !!! */
if (fep->link) {
@@ -467,11 +469,13 @@ fec_stop(struct net_device *ndev)
printk("fec_stop : Graceful transmit stop did not complete !\n");
}
- /* Whack a reset. We should wait for this. */
- writel(1, fep->hwp + FEC_ECNTRL);
- udelay(10);
- writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
- writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
+ if (!(id_entry->driver_data & FEC_QUIRK_ENET_MAC)) {
+ /* Whack a reset. We should wait for this. */
+ writel(1, fep->hwp + FEC_ECNTRL);
+ udelay(10);
+ writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
+ writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
+ }
}
but this feels wrong because sending and receiving isn't disabled in
hardware without link then.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply related
* Re: [PATCH 1/9] mm: add a "struct subpage" type containing a page, offset and length
From: Ian Campbell @ 2011-10-10 12:27 UTC (permalink / raw)
To: linux-mm@kvack.org; +Cc: netdev@vger.kernel.org
In-Reply-To: <1318245101-16890-1-git-send-email-ian.campbell@citrix.com>
On Mon, 2011-10-10 at 12:11 +0100, Ian Campbell wrote:
> Cc: linux-mm@kvack.org
> ---
> include/linux/mm_types.h | 11 +++++++++++
> 1 files changed, 11 insertions(+), 0 deletions(-)
get_maintainers.pl didn't pick up on this CC. Since mm_types.h was split
out of mm.h does the following make sense? Not sure if mm_*.h (or just
mm_inline.hm?) also makes sense.
8<--------------------------
Subject: MAINTAINER: mm subsystem includes mm_types.h
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
diff --git a/MAINTAINERS b/MAINTAINERS
index ae8820e..f10a7ea 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4212,6 +4212,7 @@ L: linux-mm@kvack.org
W: http://www.linux-mm.org
S: Maintained
F: include/linux/mm.h
+F: include/linux/mm_types.h
F: mm/
MEMORY RESOURCE CONTROLLER
>
> diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
> index 774b895..dc1d103 100644
> --- a/include/linux/mm_types.h
> +++ b/include/linux/mm_types.h
> @@ -135,6 +135,17 @@ struct page {
> #endif
> ;
>
> +struct subpage {
> + struct page *page;
> +#if (BITS_PER_LONG > 32) || (PAGE_SIZE >= 65536)
> + __u32 page_offset;
> + __u32 size;
> +#else
> + __u16 page_offset;
> + __u16 size;
> +#endif
> +};
> +
> typedef unsigned long __nocast vm_flags_t;
>
> /*
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* [PATCH 9/9] net: add opaque struct around skb frag page
From: Ian Campbell @ 2011-10-10 11:11 UTC (permalink / raw)
To: netdev; +Cc: Ian Campbell
In-Reply-To: <1318245076.21903.408.camel@zakaz.uk.xensource.com>
I've split this bit out of the skb frag destructor patch since it helps enforce
the use of the fragment API.
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
include/linux/skbuff.h | 10 ++++++----
net/core/skbuff.c | 6 +++---
2 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index ac6b05a..f881d75 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -135,7 +135,9 @@ struct sk_buff;
typedef struct skb_frag_struct skb_frag_t;
struct skb_frag_struct {
- struct page *page;
+ struct {
+ struct page *p;
+ } page;
#if (BITS_PER_LONG > 32) || (PAGE_SIZE >= 65536)
__u32 page_offset;
__u32 size;
@@ -1149,7 +1151,7 @@ static inline void __skb_fill_page_desc(struct sk_buff *skb, int i,
{
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
- frag->page = page;
+ frag->page.p = page;
frag->page_offset = off;
frag->size = size;
}
@@ -1673,7 +1675,7 @@ static inline void netdev_free_page(struct net_device *dev, struct page *page)
*/
static inline struct page *skb_frag_page(const skb_frag_t *frag)
{
- return frag->page;
+ return frag->page.p;
}
/**
@@ -1759,7 +1761,7 @@ static inline void *skb_frag_address_safe(const skb_frag_t *frag)
*/
static inline void __skb_frag_set_page(skb_frag_t *frag, struct page *page)
{
- frag->page = page;
+ frag->page.p = page;
__skb_frag_ref(frag);
}
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 5b2c5f1..6305076 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -657,14 +657,14 @@ int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask)
/* skb frags release userspace buffers */
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
- put_page(skb_shinfo(skb)->frags[i].page);
+ skb_frag_unref(skb, i);
uarg->callback(uarg);
/* skb frags point to kernel buffers */
for (i = skb_shinfo(skb)->nr_frags; i > 0; i--) {
- skb_shinfo(skb)->frags[i - 1].page_offset = 0;
- skb_shinfo(skb)->frags[i - 1].page = head;
+ __skb_fill_page_desc(skb, i-1, head, 0,
+ skb_shinfo(skb)->frags[i - 1].size);
head = (struct page *)head->private;
}
--
1.7.2.5
^ permalink raw reply related
* [PATCH 8/9] ll_temac: convert to SKB paged frag API.
From: Ian Campbell @ 2011-10-10 11:11 UTC (permalink / raw)
To: netdev; +Cc: Ian Campbell
In-Reply-To: <1318245076.21903.408.camel@zakaz.uk.xensource.com>
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Cc: netdev@vger.kernel.org
---
drivers/net/ethernet/xilinx/ll_temac_main.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c
index 570776e..66e3c36 100644
--- a/drivers/net/ethernet/xilinx/ll_temac_main.c
+++ b/drivers/net/ethernet/xilinx/ll_temac_main.c
@@ -715,8 +715,7 @@ static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
cur_p = &lp->tx_bd_v[lp->tx_bd_tail];
cur_p->phys = dma_map_single(ndev->dev.parent,
- (void *)page_address(frag->page) +
- frag->page_offset,
+ skb_frag_address(frag),
frag->size, DMA_TO_DEVICE);
cur_p->len = frag->size;
cur_p->app0 = 0;
--
1.7.2.5
^ permalink raw reply related
* [PATCH 7/9] emac: convert to SKB paged frag API.
From: Ian Campbell @ 2011-10-10 11:11 UTC (permalink / raw)
To: netdev; +Cc: Ian Campbell
In-Reply-To: <1318245076.21903.408.camel@zakaz.uk.xensource.com>
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Cc: netdev@vger.kernel.org
---
drivers/net/ethernet/ibm/emac/core.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c
index a573df1..6b3a033 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -1458,8 +1458,8 @@ static int emac_start_xmit_sg(struct sk_buff *skb, struct net_device *ndev)
if (unlikely(dev->tx_cnt + mal_tx_chunks(len) >= NUM_TX_BUFF))
goto undo_frame;
- pd = dma_map_page(&dev->ofdev->dev, frag->page, frag->page_offset, len,
- DMA_TO_DEVICE);
+ pd = skb_frag_dma_map(&dev->ofdev->dev, frag, 0, len,
+ DMA_TO_DEVICE);
slot = emac_xmit_split(dev, slot, pd, len, i == nr_frags - 1,
ctrl);
--
1.7.2.5
^ permalink raw reply related
* [PATCH 6/9] ehea: convert to SKB paged frag API
From: Ian Campbell @ 2011-10-10 11:11 UTC (permalink / raw)
To: netdev; +Cc: Ian Campbell, Breno Leitao
In-Reply-To: <1318245076.21903.408.camel@zakaz.uk.xensource.com>
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Cc: Breno Leitao <leitao@linux.vnet.ibm.com>
Cc: netdev@vger.kernel.org
---
drivers/net/ethernet/ibm/ehea/ehea_main.c | 11 +++--------
1 files changed, 3 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c
index c821cb6..dfefe80 100644
--- a/drivers/net/ethernet/ibm/ehea/ehea_main.c
+++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c
@@ -1817,8 +1817,7 @@ static inline void write_swqe2_data(struct sk_buff *skb, struct net_device *dev,
sg1entry->l_key = lkey;
sg1entry->len = frag->size;
sg1entry->vaddr =
- ehea_map_vaddr(page_address(frag->page)
- + frag->page_offset);
+ ehea_map_vaddr(skb_frag_address(frag));
swqe->descriptors++;
sg1entry_contains_frag_data = 1;
}
@@ -1830,9 +1829,7 @@ static inline void write_swqe2_data(struct sk_buff *skb, struct net_device *dev,
sgentry->l_key = lkey;
sgentry->len = frag->size;
- sgentry->vaddr =
- ehea_map_vaddr(page_address(frag->page)
- + frag->page_offset);
+ sgentry->vaddr = ehea_map_vaddr(skb_frag_address(frag));
swqe->descriptors++;
}
}
@@ -2222,9 +2219,7 @@ static void ehea_xmit3(struct sk_buff *skb, struct net_device *dev,
/* ... then copy data from the fragments */
for (i = 0; i < nfrags; i++) {
frag = &skb_shinfo(skb)->frags[i];
- memcpy(imm_data,
- page_address(frag->page) + frag->page_offset,
- frag->size);
+ memcpy(imm_data, skb_frag_address(frag), frag->size);
imm_data += frag->size;
}
}
--
1.7.2.5
^ permalink raw reply related
* [PATCH 5/9] cxgbi: convert to SKB paged frag API.
From: Ian Campbell @ 2011-10-10 11:11 UTC (permalink / raw)
To: netdev
Cc: Ian Campbell, James E.J. Bottomley, David S. Miller,
Mike Christie, James Bottomley, Karen Xie, linux-scsi
In-Reply-To: <1318245076.21903.408.camel@zakaz.uk.xensource.com>
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Cc: "James E.J. Bottomley" <JBottomley@parallels.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Mike Christie <michaelc@cs.wisc.edu>
Cc: James Bottomley <James.Bottomley@suse.de>
Cc: Karen Xie <kxie@chelsio.com>
Cc: linux-scsi@vger.kernel.org
Cc: netdev@vger.kernel.org
---
drivers/scsi/cxgbi/libcxgbi.c | 16 +++++++++-------
drivers/scsi/cxgbi/libcxgbi.h | 2 +-
2 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
index 77ac217..628b23d 100644
--- a/drivers/scsi/cxgbi/libcxgbi.c
+++ b/drivers/scsi/cxgbi/libcxgbi.c
@@ -1787,7 +1787,7 @@ static int sgl_seek_offset(struct scatterlist *sgl, unsigned int sgcnt,
}
static int sgl_read_to_frags(struct scatterlist *sg, unsigned int sgoffset,
- unsigned int dlen, skb_frag_t *frags,
+ unsigned int dlen, struct subpage *frags,
int frag_max)
{
unsigned int datalen = dlen;
@@ -1944,7 +1944,7 @@ int cxgbi_conn_init_pdu(struct iscsi_task *task, unsigned int offset,
if (tdata->nr_frags > MAX_SKB_FRAGS ||
(padlen && tdata->nr_frags == MAX_SKB_FRAGS)) {
char *dst = skb->data + task->hdr_len;
- skb_frag_t *frag = tdata->frags;
+ struct subpage *frag = tdata->frags;
/* data fits in the skb's headroom */
for (i = 0; i < tdata->nr_frags; i++, frag++) {
@@ -1962,11 +1962,13 @@ int cxgbi_conn_init_pdu(struct iscsi_task *task, unsigned int offset,
skb_put(skb, count + padlen);
} else {
/* data fit into frag_list */
- for (i = 0; i < tdata->nr_frags; i++)
- get_page(tdata->frags[i].page);
-
- memcpy(skb_shinfo(skb)->frags, tdata->frags,
- sizeof(skb_frag_t) * tdata->nr_frags);
+ for (i = 0; i < tdata->nr_frags; i++) {
+ __skb_fill_page_desc(skb, i,
+ tdata->frags[i].page,
+ tdata->frags[i].page_offset,
+ tdata->frags[i].size);
+ skb_frag_ref(skb, i);
+ }
skb_shinfo(skb)->nr_frags = tdata->nr_frags;
skb->len += count;
skb->data_len += count;
diff --git a/drivers/scsi/cxgbi/libcxgbi.h b/drivers/scsi/cxgbi/libcxgbi.h
index 9267844..9406759 100644
--- a/drivers/scsi/cxgbi/libcxgbi.h
+++ b/drivers/scsi/cxgbi/libcxgbi.h
@@ -574,7 +574,7 @@ struct cxgbi_endpoint {
#define MAX_PDU_FRAGS ((ULP2_MAX_PDU_PAYLOAD + 512 - 1) / 512)
struct cxgbi_task_data {
unsigned short nr_frags;
- skb_frag_t frags[MAX_PDU_FRAGS];
+ struct subpage frags[MAX_PDU_FRAGS];
struct sk_buff *skb;
unsigned int offset;
unsigned int count;
--
1.7.2.5
^ permalink raw reply related
* [PATCH 4/9] cxgb4vf: convert to SKB paged frag API.
From: Ian Campbell @ 2011-10-10 11:11 UTC (permalink / raw)
To: netdev; +Cc: Ian Campbell, Casey Leedom
In-Reply-To: <1318245076.21903.408.camel@zakaz.uk.xensource.com>
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Cc: Casey Leedom <leedom@chelsio.com>
Cc: netdev@vger.kernel.org
---
drivers/net/ethernet/chelsio/cxgb4vf/adapter.h | 2 +-
drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 80 ++++++++++--------------
2 files changed, 35 insertions(+), 47 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h
index 594334d..a9f2e34 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h
@@ -144,7 +144,7 @@ struct sge_fl {
* An ingress packet gather list.
*/
struct pkt_gl {
- skb_frag_t frags[MAX_SKB_FRAGS];
+ struct subpage frags[MAX_SKB_FRAGS];
void *va; /* virtual address of first byte */
unsigned int nfrags; /* # of fragments */
unsigned int tot_len; /* total length of fragments */
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
index cffb328..27f3134 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
@@ -296,8 +296,8 @@ static int map_skb(struct device *dev, const struct sk_buff *skb,
si = skb_shinfo(skb);
end = &si->frags[si->nr_frags];
for (fp = si->frags; fp < end; fp++) {
- *++addr = dma_map_page(dev, fp->page, fp->page_offset, fp->size,
- DMA_TO_DEVICE);
+ *++addr = skb_frag_dma_map(dev, fp, 0, fp->size,
+ DMA_TO_DEVICE);
if (dma_mapping_error(dev, *addr))
goto unwind;
}
@@ -1357,6 +1357,35 @@ out_free:
}
/**
+ * copy_frags - copy fragments from gather list into skb_shared_info
+ * @si: destination skb shared info structure
+ * @gl: source internal packet gather list
+ * @offset: packet start offset in first page
+ *
+ * Copy an internal packet gather list into a Linux skb_shared_info
+ * structure.
+ */
+static inline void copy_frags(struct sk_buff *skb,
+ const struct pkt_gl *gl,
+ unsigned int offset)
+{
+ int i;
+
+ /* usually there's just one frag */
+ __skb_fill_page_desc(skb, 0, gl->frags[0].page,
+ gl->frags[0].page_offset + offset,
+ gl->frags[0].size - offset);
+ skb_shinfo(skb)->nr_frags = gl->nfrags;
+ for (i = 1; i < gl->nfrags; i++)
+ __skb_fill_page_desc(skb, i, gl->frags[i].page,
+ gl->frags[i].page_offset,
+ gl->frags[i].size);
+
+ /* get a reference to the last page, we don't own it */
+ get_page(gl->frags[gl->nfrags - 1].page);
+}
+
+/**
* t4vf_pktgl_to_skb - build an sk_buff from a packet gather list
* @gl: the gather list
* @skb_len: size of sk_buff main body if it carries fragments
@@ -1369,7 +1398,6 @@ struct sk_buff *t4vf_pktgl_to_skb(const struct pkt_gl *gl,
unsigned int skb_len, unsigned int pull_len)
{
struct sk_buff *skb;
- struct skb_shared_info *ssi;
/*
* If the ingress packet is small enough, allocate an skb large enough
@@ -1396,21 +1424,10 @@ struct sk_buff *t4vf_pktgl_to_skb(const struct pkt_gl *gl,
__skb_put(skb, pull_len);
skb_copy_to_linear_data(skb, gl->va, pull_len);
- ssi = skb_shinfo(skb);
- ssi->frags[0].page = gl->frags[0].page;
- ssi->frags[0].page_offset = gl->frags[0].page_offset + pull_len;
- ssi->frags[0].size = gl->frags[0].size - pull_len;
- if (gl->nfrags > 1)
- memcpy(&ssi->frags[1], &gl->frags[1],
- (gl->nfrags-1) * sizeof(skb_frag_t));
- ssi->nr_frags = gl->nfrags;
-
+ copy_frags(skb, gl, pull_len);
skb->len = gl->tot_len;
skb->data_len = skb->len - pull_len;
skb->truesize += skb->data_len;
-
- /* Get a reference for the last page, we don't own it */
- get_page(gl->frags[gl->nfrags - 1].page);
}
out:
@@ -1434,35 +1451,6 @@ void t4vf_pktgl_free(const struct pkt_gl *gl)
}
/**
- * copy_frags - copy fragments from gather list into skb_shared_info
- * @si: destination skb shared info structure
- * @gl: source internal packet gather list
- * @offset: packet start offset in first page
- *
- * Copy an internal packet gather list into a Linux skb_shared_info
- * structure.
- */
-static inline void copy_frags(struct skb_shared_info *si,
- const struct pkt_gl *gl,
- unsigned int offset)
-{
- unsigned int n;
-
- /* usually there's just one frag */
- si->frags[0].page = gl->frags[0].page;
- si->frags[0].page_offset = gl->frags[0].page_offset + offset;
- si->frags[0].size = gl->frags[0].size - offset;
- si->nr_frags = gl->nfrags;
-
- n = gl->nfrags - 1;
- if (n)
- memcpy(&si->frags[1], &gl->frags[1], n * sizeof(skb_frag_t));
-
- /* get a reference to the last page, we don't own it */
- get_page(gl->frags[n].page);
-}
-
-/**
* do_gro - perform Generic Receive Offload ingress packet processing
* @rxq: ingress RX Ethernet Queue
* @gl: gather list for ingress packet
@@ -1484,7 +1472,7 @@ static void do_gro(struct sge_eth_rxq *rxq, const struct pkt_gl *gl,
return;
}
- copy_frags(skb_shinfo(skb), gl, PKTSHIFT);
+ copy_frags(skb, gl, PKTSHIFT);
skb->len = gl->tot_len - PKTSHIFT;
skb->data_len = skb->len;
skb->truesize += skb->data_len;
@@ -1667,7 +1655,7 @@ int process_responses(struct sge_rspq *rspq, int budget)
rmb();
rsp_type = RSPD_TYPE(rc->type_gen);
if (likely(rsp_type == RSP_TYPE_FLBUF)) {
- skb_frag_t *fp;
+ struct subpage *fp;
struct pkt_gl gl;
const struct rx_sw_desc *sdesc;
u32 bufsz, frag;
--
1.7.2.5
^ permalink raw reply related
* [PATCH 3/9] cxgb4: convert to SKB paged frag API.
From: Ian Campbell @ 2011-10-10 11:11 UTC (permalink / raw)
To: netdev; +Cc: Ian Campbell, Dimitris Michailidis
In-Reply-To: <1318245076.21903.408.camel@zakaz.uk.xensource.com>
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Cc: Dimitris Michailidis <dm@chelsio.com>
Cc: netdev@vger.kernel.org
---
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 2 +-
drivers/net/ethernet/chelsio/cxgb4/sge.c | 33 ++++++++++++++-------------
2 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index 223a7f7..209cd69 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -326,7 +326,7 @@ struct sge_fl { /* SGE free-buffer queue state */
/* A packet gather list */
struct pkt_gl {
- skb_frag_t frags[MAX_SKB_FRAGS];
+ struct subpage frags[MAX_SKB_FRAGS];
void *va; /* virtual address of first byte */
unsigned int nfrags; /* # of fragments */
unsigned int tot_len; /* total length of fragments */
diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c
index 56adf44..0100c4c 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c
@@ -215,8 +215,8 @@ static int map_skb(struct device *dev, const struct sk_buff *skb,
end = &si->frags[si->nr_frags];
for (fp = si->frags; fp < end; fp++) {
- *++addr = dma_map_page(dev, fp->page, fp->page_offset, fp->size,
- DMA_TO_DEVICE);
+ *++addr = skb_frag_dma_map(dev, fp, 0, fp->size,
+ DMA_TO_DEVICE);
if (dma_mapping_error(dev, *addr))
goto unwind;
}
@@ -1409,22 +1409,23 @@ int cxgb4_ofld_send(struct net_device *dev, struct sk_buff *skb)
}
EXPORT_SYMBOL(cxgb4_ofld_send);
-static inline void copy_frags(struct skb_shared_info *ssi,
+static inline void copy_frags(struct sk_buff *skb,
const struct pkt_gl *gl, unsigned int offset)
{
- unsigned int n;
+ int i;
/* usually there's just one frag */
- ssi->frags[0].page = gl->frags[0].page;
- ssi->frags[0].page_offset = gl->frags[0].page_offset + offset;
- ssi->frags[0].size = gl->frags[0].size - offset;
- ssi->nr_frags = gl->nfrags;
- n = gl->nfrags - 1;
- if (n)
- memcpy(&ssi->frags[1], &gl->frags[1], n * sizeof(skb_frag_t));
+ __skb_fill_page_desc(skb, 0, gl->frags[0].page,
+ gl->frags[0].page_offset + offset,
+ gl->frags[0].size - offset);
+ skb_shinfo(skb)->nr_frags = gl->nfrags;
+ for (i = 1; i < gl->nfrags; i++)
+ __skb_fill_page_desc(skb, i, gl->frags[i].page,
+ gl->frags[i].page_offset,
+ gl->frags[i].size);
/* get a reference to the last page, we don't own it */
- get_page(gl->frags[n].page);
+ get_page(gl->frags[gl->nfrags - 1].page);
}
/**
@@ -1459,7 +1460,7 @@ struct sk_buff *cxgb4_pktgl_to_skb(const struct pkt_gl *gl,
__skb_put(skb, pull_len);
skb_copy_to_linear_data(skb, gl->va, pull_len);
- copy_frags(skb_shinfo(skb), gl, pull_len);
+ copy_frags(skb, gl, pull_len);
skb->len = gl->tot_len;
skb->data_len = skb->len - pull_len;
skb->truesize += skb->data_len;
@@ -1478,7 +1479,7 @@ EXPORT_SYMBOL(cxgb4_pktgl_to_skb);
static void t4_pktgl_free(const struct pkt_gl *gl)
{
int n;
- const skb_frag_t *p;
+ const struct subpage *p;
for (p = gl->frags, n = gl->nfrags - 1; n--; p++)
put_page(p->page);
@@ -1522,7 +1523,7 @@ static void do_gro(struct sge_eth_rxq *rxq, const struct pkt_gl *gl,
return;
}
- copy_frags(skb_shinfo(skb), gl, RX_PKT_PAD);
+ copy_frags(skb, gl, RX_PKT_PAD);
skb->len = gl->tot_len - RX_PKT_PAD;
skb->data_len = skb->len;
skb->truesize += skb->data_len;
@@ -1698,7 +1699,7 @@ static int process_responses(struct sge_rspq *q, int budget)
rmb();
rsp_type = RSPD_TYPE(rc->type_gen);
if (likely(rsp_type == RSP_TYPE_FLBUF)) {
- skb_frag_t *fp;
+ struct subpage *fp;
struct pkt_gl si;
const struct rx_sw_desc *rsd;
u32 len = ntohl(rc->pldbuflen_qid), bufsz, frags;
--
1.7.2.5
^ permalink raw reply related
* [PATCH 2/9] mlx4: convert to SKB paged frag API.
From: Ian Campbell @ 2011-10-10 11:11 UTC (permalink / raw)
To: netdev; +Cc: Ian Campbell
In-Reply-To: <1318245076.21903.408.camel@zakaz.uk.xensource.com>
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Cc: netdev@vger.kernel.org
---
drivers/net/ethernet/mellanox/mlx4/en_rx.c | 34 ++++++++++++++--------------
drivers/net/ethernet/mellanox/mlx4/en_tx.c | 20 +++-------------
2 files changed, 21 insertions(+), 33 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
index 37cc9e5..12e0bee 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
@@ -44,7 +44,7 @@
static int mlx4_en_alloc_frag(struct mlx4_en_priv *priv,
struct mlx4_en_rx_desc *rx_desc,
- struct skb_frag_struct *skb_frags,
+ struct subpage *skb_frags,
struct mlx4_en_rx_alloc *ring_alloc,
int i)
{
@@ -157,8 +157,8 @@ static int mlx4_en_prepare_rx_desc(struct mlx4_en_priv *priv,
struct mlx4_en_rx_ring *ring, int index)
{
struct mlx4_en_rx_desc *rx_desc = ring->buf + (index * ring->stride);
- struct skb_frag_struct *skb_frags = ring->rx_info +
- (index << priv->log_rx_info);
+ struct subpage *skb_frags = ring->rx_info +
+ (index << priv->log_rx_info);
int i;
for (i = 0; i < priv->num_frags; i++)
@@ -183,7 +183,7 @@ static void mlx4_en_free_rx_desc(struct mlx4_en_priv *priv,
int index)
{
struct mlx4_en_dev *mdev = priv->mdev;
- struct skb_frag_struct *skb_frags;
+ struct subpage *skb_frags;
struct mlx4_en_rx_desc *rx_desc = ring->buf + (index << ring->log_stride);
dma_addr_t dma;
int nr;
@@ -403,8 +403,8 @@ void mlx4_en_deactivate_rx_ring(struct mlx4_en_priv *priv,
/* Unmap a completed descriptor and free unused pages */
static int mlx4_en_complete_rx_desc(struct mlx4_en_priv *priv,
struct mlx4_en_rx_desc *rx_desc,
- struct skb_frag_struct *skb_frags,
- struct skb_frag_struct *skb_frags_rx,
+ struct subpage *skb_frags,
+ struct sk_buff *skb,
struct mlx4_en_rx_alloc *page_alloc,
int length)
{
@@ -420,9 +420,10 @@ static int mlx4_en_complete_rx_desc(struct mlx4_en_priv *priv,
break;
/* Save page reference in skb */
- skb_frags_rx[nr].page = skb_frags[nr].page;
- skb_frags_rx[nr].size = skb_frags[nr].size;
- skb_frags_rx[nr].page_offset = skb_frags[nr].page_offset;
+ __skb_fill_page_desc(skb, nr,
+ skb_frags[nr].page,
+ skb_frags[nr].size,
+ skb_frags[nr].page_offset);
dma = be64_to_cpu(rx_desc->data[nr].addr);
/* Allocate a replacement page */
@@ -430,12 +431,12 @@ static int mlx4_en_complete_rx_desc(struct mlx4_en_priv *priv,
goto fail;
/* Unmap buffer */
- pci_unmap_single(mdev->pdev, dma, skb_frags_rx[nr].size,
+ pci_unmap_single(mdev->pdev, dma, skb_shinfo(skb)->frags[nr].size,
PCI_DMA_FROMDEVICE);
}
/* Adjust size of last fragment to match actual length */
if (nr > 0)
- skb_frags_rx[nr - 1].size = length -
+ skb_shinfo(skb)->frags[nr - 1].size = length -
priv->frag_info[nr - 1].frag_prefix_size;
return nr;
@@ -444,7 +445,7 @@ fail:
* the descriptor) of this packet; remaining fragments are reused... */
while (nr > 0) {
nr--;
- put_page(skb_frags_rx[nr].page);
+ skb_frag_unref(skb, nr);
}
return 0;
}
@@ -452,7 +453,7 @@ fail:
static struct sk_buff *mlx4_en_rx_skb(struct mlx4_en_priv *priv,
struct mlx4_en_rx_desc *rx_desc,
- struct skb_frag_struct *skb_frags,
+ struct subpage *skb_frags,
struct mlx4_en_rx_alloc *page_alloc,
unsigned int length)
{
@@ -490,8 +491,7 @@ static struct sk_buff *mlx4_en_rx_skb(struct mlx4_en_priv *priv,
/* Move relevant fragments to skb */
used_frags = mlx4_en_complete_rx_desc(priv, rx_desc, skb_frags,
- skb_shinfo(skb)->frags,
- page_alloc, length);
+ skb, page_alloc, length);
if (unlikely(!used_frags)) {
kfree_skb(skb);
return NULL;
@@ -533,7 +533,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
struct mlx4_en_priv *priv = netdev_priv(dev);
struct mlx4_cqe *cqe;
struct mlx4_en_rx_ring *ring = &priv->rx_ring[cq->ring];
- struct skb_frag_struct *skb_frags;
+ struct subpage *skb_frags;
struct mlx4_en_rx_desc *rx_desc;
struct sk_buff *skb;
int index;
@@ -600,7 +600,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
nr = mlx4_en_complete_rx_desc(
priv, rx_desc,
- skb_frags, skb_shinfo(gro_skb)->frags,
+ skb_frags, gro_skb,
ring->page_alloc, length);
if (!nr)
goto next;
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
index 6e03de0..e8cc987 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
@@ -460,26 +460,13 @@ static inline void mlx4_en_xmit_poll(struct mlx4_en_priv *priv, int tx_ind)
}
}
-static void *get_frag_ptr(struct sk_buff *skb)
-{
- struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[0];
- struct page *page = frag->page;
- void *ptr;
-
- ptr = page_address(page);
- if (unlikely(!ptr))
- return NULL;
-
- return ptr + frag->page_offset;
-}
-
static int is_inline(struct sk_buff *skb, void **pfrag)
{
void *ptr;
if (inline_thold && !skb_is_gso(skb) && skb->len <= inline_thold) {
if (skb_shinfo(skb)->nr_frags == 1) {
- ptr = get_frag_ptr(skb);
+ ptr = skb_frag_address_safe(&skb_shinfo(skb)->frags[0]);
if (unlikely(!ptr))
return 0;
@@ -756,8 +743,9 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
/* Map fragments */
for (i = skb_shinfo(skb)->nr_frags - 1; i >= 0; i--) {
frag = &skb_shinfo(skb)->frags[i];
- dma = pci_map_page(mdev->dev->pdev, frag->page, frag->page_offset,
- frag->size, PCI_DMA_TODEVICE);
+ dma = skb_frag_dma_map(&mdev->dev->pdev->dev, frag,
+ 0, frag->size,
+ DMA_TO_DEVICE);
data->addr = cpu_to_be64(dma);
data->lkey = cpu_to_be32(mdev->mr.key);
wmb();
--
1.7.2.5
^ 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