* [PATCH] tcp: Replace time wait bucket msg by counter.
From: Tom Herbert @ 2010-12-04 21:35 UTC (permalink / raw)
To: davem, netdev
Rather than printing the message to the log, use a mib counter to keep
track of the count of occurences of time wait bucket overflow. Reduces
spam in logs.
Signed-off-by: Tom Herbert <therbert@google.com>
---
include/linux/snmp.h | 1 +
net/ipv4/proc.c | 1 +
net/ipv4/tcp_minisocks.c | 2 +-
3 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/include/linux/snmp.h b/include/linux/snmp.h
index ebb0c80..12b2b18 100644
--- a/include/linux/snmp.h
+++ b/include/linux/snmp.h
@@ -230,6 +230,7 @@ enum
LINUX_MIB_TCPMINTTLDROP, /* RFC 5082 */
LINUX_MIB_TCPDEFERACCEPTDROP,
LINUX_MIB_IPRPFILTER, /* IP Reverse Path Filter (rp_filter) */
+ LINUX_MIB_TCPTIMEWAITOVERFLOW, /* TCPTimeWaitOverflow */
__LINUX_MIB_MAX
};
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index 1b48eb1..b14ec7d 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -253,6 +253,7 @@ static const struct snmp_mib snmp4_net_list[] = {
SNMP_MIB_ITEM("TCPMinTTLDrop", LINUX_MIB_TCPMINTTLDROP),
SNMP_MIB_ITEM("TCPDeferAcceptDrop", LINUX_MIB_TCPDEFERACCEPTDROP),
SNMP_MIB_ITEM("IPReversePathFilter", LINUX_MIB_IPRPFILTER),
+ SNMP_MIB_ITEM("TCPTimeWaitOverflow", LINUX_MIB_TCPTIMEWAITOVERFLOW),
SNMP_MIB_SENTINEL
};
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 43cf901..3052a2b 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -347,7 +347,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)
* socket up. We've got bigger problems than
* non-graceful socket closings.
*/
- LIMIT_NETDEBUG(KERN_INFO "TCP: time wait bucket table overflow\n");
+ NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPTIMEWAITOVERFLOW);
}
tcp_update_metrics(sk);
--
1.7.3.1
^ permalink raw reply related
* Re: [PATCH] tcp: Replace time wait bucket msg by counter.
From: Eric Dumazet @ 2010-12-04 21:52 UTC (permalink / raw)
To: Tom Herbert; +Cc: davem, netdev
In-Reply-To: <alpine.DEB.2.00.1012041331220.6278@pokey.mtv.corp.google.com>
Le samedi 04 décembre 2010 à 13:35 -0800, Tom Herbert a écrit :
> Rather than printing the message to the log, use a mib counter to keep
> track of the count of occurences of time wait bucket overflow. Reduces
> spam in logs.
>
> Signed-off-by: Tom Herbert <therbert@google.com>
> ---
>
> diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
> index 43cf901..3052a2b 100644
> --- a/net/ipv4/tcp_minisocks.c
> +++ b/net/ipv4/tcp_minisocks.c
> @@ -347,7 +347,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)
> * socket up. We've got bigger problems than
> * non-graceful socket closings.
> */
> - LIMIT_NETDEBUG(KERN_INFO "TCP: time wait bucket table overflow\n");
> + NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPTIMEWAITOVERFLOW);
> }
>
> tcp_update_metrics(sk);
NET_INC_STATS_BH() should be more appropriate, since we are in a
softirq ?
^ permalink raw reply
* Re: [PATCH 0/5 V2] Firewire networking assorted fixes
From: Maxim Levitsky @ 2010-12-04 23:14 UTC (permalink / raw)
To: linux1394-devel; +Cc: Stefan Richter, netdev
In-Reply-To: <1290996593-32416-1-git-send-email-maximlevitsky@gmail.com>
On Mon, 2010-11-29 at 04:09 +0200, Maxim Levitsky wrote:
> Hi,
>
> This is updated version of the patches.
> I updated the changelogs, addressed comments on patch #2
>
> Best regards,
> Maxim Levitsky
>
Any update?
Best regards,
Maxim Levitsky
^ permalink raw reply
* Re: [PATCH 3/5] NET: IPV4: ARP: allow to invalidate specific ARP entries
From: Maxim Levitsky @ 2010-12-04 23:15 UTC (permalink / raw)
To: linux1394-devel
Cc: Stefan Richter, netdev, David S. Miller, Alexey Kuznetsov,
James Morris, Patrick McHardy
In-Reply-To: <1290996593-32416-4-git-send-email-maximlevitsky@gmail.com>
On Mon, 2010-11-29 at 04:09 +0200, Maxim Levitsky wrote:
> IPv4 over firewire needs to be able to remove ARP entries
> from the ARP cache that belong to nodes that are removed, because
> IPv4 over firewire uses ARP packets for private information
> about nodes.
>
> This information becomes invalid as soon as node drops
> off the bus and when it reconnects, its only possible
> to start takling to is after it responded to an ARP packet.
> But ARP cache prevents such packets from being sent.
>
> CC: netdev@vger.kernel.org
> CC: "David S. Miller" <davem@davemloft.net>
> CC: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
> CC: James Morris <jmorris@namei.org>
> CC: Patrick McHardy <kaber@trash.net>
Anybody?
Best regards,
Maxim Levitsky
>
>
> Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
> ---
> include/net/arp.h | 1 +
> net/ipv4/arp.c | 29 ++++++++++++++++++-----------
> 2 files changed, 19 insertions(+), 11 deletions(-)
>
> diff --git a/include/net/arp.h b/include/net/arp.h
> index f4cf6ce..91f0568 100644
> --- a/include/net/arp.h
> +++ b/include/net/arp.h
> @@ -25,5 +25,6 @@ extern struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
> const unsigned char *src_hw,
> const unsigned char *target_hw);
> extern void arp_xmit(struct sk_buff *skb);
> +int arp_invalidate(struct net_device *dev, __be32 ip);
>
> #endif /* _ARP_H */
> diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
> index d8e540c..35b1272 100644
> --- a/net/ipv4/arp.c
> +++ b/net/ipv4/arp.c
> @@ -1142,6 +1142,23 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev)
> return err;
> }
>
> +int arp_invalidate(struct net_device *dev, __be32 ip)
> +{
> + int err = -ENXIO;
> + struct neighbour *neigh = neigh_lookup(&arp_tbl, &ip, dev);
> +
> + if (neigh) {
> + if (neigh->nud_state & ~NUD_NOARP)
> + err = neigh_update(neigh, NULL, NUD_FAILED,
> + NEIGH_UPDATE_F_OVERRIDE|
> + NEIGH_UPDATE_F_ADMIN);
> + neigh_release(neigh);
> + }
> +
> + return err;
> +}
> +EXPORT_SYMBOL(arp_invalidate);
> +
> static int arp_req_delete_public(struct net *net, struct arpreq *r,
> struct net_device *dev)
> {
> @@ -1162,7 +1179,6 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
> {
> int err;
> __be32 ip;
> - struct neighbour *neigh;
>
> if (r->arp_flags & ATF_PUBL)
> return arp_req_delete_public(net, r, dev);
> @@ -1180,16 +1196,7 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
> if (!dev)
> return -EINVAL;
> }
> - err = -ENXIO;
> - neigh = neigh_lookup(&arp_tbl, &ip, dev);
> - if (neigh) {
> - if (neigh->nud_state & ~NUD_NOARP)
> - err = neigh_update(neigh, NULL, NUD_FAILED,
> - NEIGH_UPDATE_F_OVERRIDE|
> - NEIGH_UPDATE_F_ADMIN);
> - neigh_release(neigh);
> - }
> - return err;
> + return arp_invalidate(dev, ip);
> }
>
> /*
^ permalink raw reply
* [PATCH net-2.6] ifb: goto resched directly if error happens and dp->tq isn't empty
From: Changli Gao @ 2010-12-05 0:09 UTC (permalink / raw)
To: David S. Miller; +Cc: Jarek Poplawski, jamal, netdev, Changli Gao
If we break the loop when there are still skbs in tq and no skb in
rq, the skbs will be left in txq until new skbs are enqueued into rq.
In rare cases, no new skb is queued, then these skbs will stay in rq
forever.
After this patch, if tq isn't empty when we break the loop, we goto
resched directly.
Signed-off-by: Changli Gao <xiaosuo@gmail.com>
---
drivers/net/ifb.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index ab9f675..fe337bd 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -104,6 +104,8 @@ static void ri_tasklet(unsigned long dev)
rcu_read_unlock();
dev_kfree_skb(skb);
stats->tx_dropped++;
+ if (skb_queue_len(&dp->tq) != 0)
+ goto resched;
break;
}
rcu_read_unlock();
^ permalink raw reply related
* Re: [PATCH 3/3] ifb: move tq from ifb_private
From: Changli Gao @ 2010-12-05 0:22 UTC (permalink / raw)
To: Jarek Poplawski; +Cc: jamal, netdev
In-Reply-To: <20101204165609.GB1981@del.dom.local>
On Sun, Dec 5, 2010 at 12:56 AM, Jarek Poplawski <jarkao2@gmail.com> wrote:
>
> I'm simply not convinced this kind of (fast) throttling can properly
> fix any of the problems (what about other flows in the queue), while
> Changli's patch makes this tasklet simpler and a bit faster.
>
The error case handled currently is the original netdev disappears but
the corresponding skbs are still in ifb.
I do also think checking the return value of netif_rx() and
dev_queue_xmit() can fix more 'problems'. :)
--
Regards,
Changli Gao(xiaosuo@gmail.com)
^ permalink raw reply
* [PATCH 3/3 v2] ifb: use the lockless variants of skb_queue
From: Changli Gao @ 2010-12-05 1:01 UTC (permalink / raw)
To: jamal; +Cc: netdev, Jarek Poplawski, Changli Gao
rq and tq are both protected by tx queue lock, so we can simply use
the lockless variants of skb_queue.
skb_queue_splice_tail_init() is used instead of the open coded and slow
one.
Signed-off-by: Changli Gao <xiaosuo@gmail.com>
---
drivers/net/ifb.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index d1e362a..9825f11 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -63,9 +63,7 @@ static void ri_tasklet(unsigned long dev)
txq = netdev_get_tx_queue(_dev, 0);
if ((skb = skb_peek(&dp->tq)) == NULL) {
if (__netif_tx_trylock(txq)) {
- while ((skb = skb_dequeue(&dp->rq)) != NULL) {
- skb_queue_tail(&dp->tq, skb);
- }
+ skb_queue_splice_tail_init(&dp->rq, &dp->tq);
__netif_tx_unlock(txq);
} else {
/* reschedule */
@@ -161,7 +159,7 @@ static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue(dev);
}
- skb_queue_tail(&dp->rq, skb);
+ __skb_queue_tail(&dp->rq, skb);
if (!dp->tasklet_pending) {
dp->tasklet_pending = 1;
tasklet_schedule(&dp->ifb_tasklet);
@@ -176,8 +174,8 @@ static int ifb_close(struct net_device *dev)
tasklet_kill(&dp->ifb_tasklet);
netif_stop_queue(dev);
- skb_queue_purge(&dp->rq);
- skb_queue_purge(&dp->tq);
+ __skb_queue_purge(&dp->rq);
+ __skb_queue_purge(&dp->tq);
return 0;
}
@@ -186,8 +184,8 @@ static int ifb_open(struct net_device *dev)
struct ifb_private *dp = netdev_priv(dev);
tasklet_init(&dp->ifb_tasklet, ri_tasklet, (unsigned long)dev);
- skb_queue_head_init(&dp->rq);
- skb_queue_head_init(&dp->tq);
+ __skb_queue_head_init(&dp->rq);
+ __skb_queue_head_init(&dp->tq);
netif_start_queue(dev);
return 0;
^ permalink raw reply related
* Re: [PATCH 3/3] ifb: move tq from ifb_private
From: Changli Gao @ 2010-12-05 1:13 UTC (permalink / raw)
To: Jarek Poplawski; +Cc: jamal, netdev
In-Reply-To: <AANLkTimnejoONxGqusiYVWOKbcy2yqbpFH-XyzgG0=87@mail.gmail.com>
On Sun, Dec 5, 2010 at 8:22 AM, Changli Gao <xiaosuo@gmail.com> wrote:
>
> The error case handled currently is the original netdev disappears but
> the corresponding skbs are still in ifb.
>
> I do also think checking the return value of netif_rx() and
> dev_queue_xmit() can fix more 'problems'. :)
>
I have posted the V2 and split the bug fix to a separate one.
BTW: My ultimate goal is making ifb a multi-queue NIC, and the number
of queues is equal to the number of the possible CPUs.
--
Regards,
Changli Gao(xiaosuo@gmail.com)
^ permalink raw reply
* [PATCH] net/9p/protocol.c: Remove duplicated macros.
From: Thiago Farina @ 2010-12-05 1:22 UTC (permalink / raw)
To: linux-kernel
Cc: David S. Miller, Eric Van Hensbergen, Sripathi Kodi,
Aneesh Kumar K.V, Venkateswararao Jujjuri, Andrew Morton, netdev
Use the macros already provided by kernel.h file.
Signed-off-by: Thiago Farina <tfransosi@gmail.com>
---
net/9p/protocol.c | 33 +++++++++------------------------
1 files changed, 9 insertions(+), 24 deletions(-)
diff --git a/net/9p/protocol.c b/net/9p/protocol.c
index 45c15f4..798beac 100644
--- a/net/9p/protocol.c
+++ b/net/9p/protocol.c
@@ -27,31 +27,16 @@
#include <linux/module.h>
#include <linux/errno.h>
+#include <linux/kernel.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
#include <linux/sched.h>
+#include <linux/stddef.h>
#include <linux/types.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include "protocol.h"
-#ifndef MIN
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#endif
-
-#ifndef MAX
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-#endif
-
-#ifndef offset_of
-#define offset_of(type, memb) \
- ((unsigned long)(&((type *)0)->memb))
-#endif
-#ifndef container_of
-#define container_of(obj, type, memb) \
- ((type *)(((char *)obj) - offset_of(type, memb)))
-#endif
-
static int
p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...);
@@ -104,7 +89,7 @@ EXPORT_SYMBOL(p9stat_free);
static size_t pdu_read(struct p9_fcall *pdu, void *data, size_t size)
{
- size_t len = MIN(pdu->size - pdu->offset, size);
+ size_t len = min(pdu->size - pdu->offset, size);
memcpy(data, &pdu->sdata[pdu->offset], len);
pdu->offset += len;
return size - len;
@@ -112,7 +97,7 @@ static size_t pdu_read(struct p9_fcall *pdu, void *data, size_t size)
static size_t pdu_write(struct p9_fcall *pdu, const void *data, size_t size)
{
- size_t len = MIN(pdu->capacity - pdu->size, size);
+ size_t len = min(pdu->capacity - pdu->size, size);
memcpy(&pdu->sdata[pdu->size], data, len);
pdu->size += len;
return size - len;
@@ -121,7 +106,7 @@ static size_t pdu_write(struct p9_fcall *pdu, const void *data, size_t size)
static size_t
pdu_write_u(struct p9_fcall *pdu, const char __user *udata, size_t size)
{
- size_t len = MIN(pdu->capacity - pdu->size, size);
+ size_t len = min(pdu->capacity - pdu->size, size);
if (copy_from_user(&pdu->sdata[pdu->size], udata, len))
len = 0;
@@ -201,7 +186,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt,
if (errcode)
break;
- size = MAX(len, 0);
+ size = max_t(int16_t, len, 0);
*sptr = kmalloc(size + 1, GFP_KERNEL);
if (*sptr == NULL) {
@@ -256,8 +241,8 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt,
p9pdu_readf(pdu, proto_version, "d", count);
if (!errcode) {
*count =
- MIN(*count,
- pdu->size - pdu->offset);
+ min_t(int32_t, *count,
+ pdu->size - pdu->offset);
*data = &pdu->sdata[pdu->offset];
}
}
@@ -421,7 +406,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
const char *sptr = va_arg(ap, const char *);
int16_t len = 0;
if (sptr)
- len = MIN(strlen(sptr), USHRT_MAX);
+ len = min_t(int16_t, strlen(sptr), USHRT_MAX);
errcode = p9pdu_writef(pdu, proto_version,
"w", len);
--
1.7.3.2.343.g7d43d
^ permalink raw reply related
* Re: [PATCH v2] ethtool : Allow ethtool to set interface in loopback mode.
From: Bill Fink @ 2010-12-05 1:33 UTC (permalink / raw)
To: David Lamparter
Cc: Ben Hutchings, Mahesh Bandewar, linux-netdev, Tom Herbert,
David Miller
In-Reply-To: <20101203164844.GB235120@jupiter.n2.diac24.net>
On Fri, 3 Dec 2010, David Lamparter wrote:
> On Fri, Dec 03, 2010 at 04:33:34PM +0000, Ben Hutchings wrote:
> > On Fri, 2010-12-03 at 17:03 +0100, David Lamparter wrote:
> > > On Thu, Dec 02, 2010 at 02:35:51PM -0800, Mahesh Bandewar wrote:
> > > > This patch adds -L command-line option to switch loopback mode on/off
> > > > and -l option to display current loopback mode on a specified interface.
> > > [...]
> > > > +.A1 on off
> > > > +Switches loopback mode
> > > > +.B on
> > > > +or
> > > > +.B off
> > >
> > > What about devices that support different kinds of loopback, like MAC
> > > loopback & PHY loopback? (No idea if we have kernel support for this
> > > either...)
> >
> > That distinction is useful for diagnostic purposes, but drivers can
> > already cover those different loopback modes in self-test. The
> > motivation for this feature is testing data path behaviour, and Mahesh
> > has specified that loopback should be enabled as near as possible to the
> > host.
>
> Ah, good enough. Thanks.
Perhaps in the future it could be extended, if desired,
to something like:
loopback=0 disabled
loopback=1 driver loopback nearest host
loopback=2 driver loopback nearest network
Both types of loopback could be useful for different purposes.
-Bill
^ permalink raw reply
* Re: [PATCH 2.6.36] vlan: Avoid hwaccel vlan packets when vid not used
From: Michael Leun @ 2010-12-05 2:07 UTC (permalink / raw)
To: Eric Dumazet
Cc: David Miller, Ben Greear, linux-kernel, netdev, Jesse Gross,
stable
In-Reply-To: <1291200914.2856.546.camel@edumazet-laptop>
On Wed, 01 Dec 2010 11:55:14 +0100
Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Le mercredi 01 décembre 2010 à 11:17 +0100, Michael Leun a écrit :
>
> > Yup, from what I've tested this works (and tcpdump sees broadcast
> > packets even for vlans not configured at the moment including vlan
> > tag
> > - yipee!).
> >
This was tested on machine with
root@tp_z61m:~/src/tcpdump-4.1.1# lspci|grep Eth
02:00.0 Ethernet controller: Broadcom Corporation NetXtreme BCM5752M Gigabit Ethernet PCI Express (rev 02)
There it works as I said.
But on
hpdl320g5:/home/ml # lspci | grep Eth
03:04.0 Ethernet controller: Broadcom Corporation NetXtreme BCM5714 Gigabit Ethernet (rev a3)
03:04.1 Ethernet controller: Broadcom Corporation NetXtreme BCM5714 Gigabit Ethernet (rev a3)
the good message is that it also does not crash, but with tcpdump I see
vlan tags when no vlan devices configured on the respective eth, if so
I do not see tags anymore vlan tags on the trunk interface.
hpdl320g5:/home/ml # ifconfig -a
[...]
eth1 Link encap:Ethernet Hardware Adresse xx:xx:xx:xx:xx:xx
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 Sendewarteschlangenlänge:1000
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
Interrupt:17
[...]
hpdl320g5:/home/ml # tcpdump -i eth1 -n -e
tcpdump: WARNING: eth1: no IPv4 address assigned
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 96 bytes
[...]
02:45:57.597640 xx:xx:xx:xx:xx:xx > ff:ff:ff:ff:ff:ff, ethertype 802.1Q (0x8100), length 64: vlan 1505, p 0, ethertype 802.1Q, vlan 99, p 3, ethertype ARP, arp who-has 10.0.0.1 tell 10.0.0.2
02:45:57.622654 xx:xx:xx:xx:xx:xx > ff:ff:ff:ff:ff:ff, ethertype 802.1Q (0x8100), length 64: vlan 1505, p 0, ethertype 802.1Q, vlan 99, p 3, ethertype ARP, arp who-has 10.0.0.1 tell 10.0.0.2
[...]
hpdl320g5:/home/ml # vconfig add eth1 2
WARNING: Could not open /proc/net/vlan/config. Maybe you need to load the 8021q module, or maybe you are not using PROCFS??
Added VLAN with VID == 2 to IF -:eth1:-
hpdl320g5:/home/ml # cat /proc/net/vlan/config
VLAN Dev name | VLAN ID
Name-Type: VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD
eth1.2 | 2 | eth1
hpdl320g5:/home/ml # tcpdump -i eth1 -n -e
tcpdump: WARNING: eth1: no IPv4 address assigned
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 96 bytes
[...]
02:50:18.095959 xx:xx:xx:xx:xx:xx > ff:ff:ff:ff:ff:ff, ethertype 802.1Q (0x8100), length 60: vlan 99, p 3, ethertype ARP, arp who-has 10.0.0.1 tell 10.0.0.2
02:50:18.120989 xx:xx:xx:xx:xx:xx > ff:ff:ff:ff:ff:ff, ethertype 802.1Q (0x8100), length 60: vlan 99, p 3, ethertype ARP, arp who-has 10.0.0.1 tell 10.0.0.2
[...]
The same packages we saw double vlan tagged a few minutes ago now appear single vlan tagged (and of course, other packets that were shown single vlan tagged before are now shown without vlan tag / eth type 0x0800).
On the other machine:
root@tp_z61m:~# cat /proc/net/vlan/config
VLAN Dev name | VLAN ID
Name-Type: VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD
eth0.741 | 741 | eth0
eth0.2 | 2 | eth0
root@tp_z61m:~/src/tcpdump-4.1.1# ./tcpdump -i eth0 -n -e not port 22
tcpdump: WARNING: eth0: no IPv4 address assigned
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
03:06:51.859016 xx:xx:xx:xx:xx:xx > ff:ff:ff:ff:ff:ff, ethertype 802.1Q (0x8100), length 64: vlan 1505, p 0, ethertype 802.1Q, vlan 99, p 3, ethertype ARP, Request who-has 10.0.0.1 tell 10.0.0.2, length 42
03:06:51.883956 xx:xx:xx:xx:xx:xx > ff:ff:ff:ff:ff:ff, ethertype 802.1Q (0x8100), length 64: vlan 1505, p 0, ethertype 802.1Q, vlan 99, p 3, ethertype ARP, Request who-has 10.0.0.1 tell 10.0.0.2, length 42
[...]
> Here is the revised patch again then for stable team, via David Miller
> agreement.
[...]
--
MfG,
Michael Leun
^ permalink raw reply
* [net-next-2.6 PATCH] enic: Add ndo_set_rx_mode support for enic vnics
From: Roopa Prabhu @ 2010-12-05 6:23 UTC (permalink / raw)
To: davem; +Cc: netdev
From: Roopa Prabhu <roprabhu@cisco.com>
Add ndo_set_rx_mode support to register unicast and multicast address filters for enic vnics
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com>
Signed-off-by: David Wang <dwang2@cisco.com>
Signed-off-by: Christian Benvenuti <benve@cisco.com>
---
drivers/net/enic/enic.h | 4 +
drivers/net/enic/enic_main.c | 121 ++++++++++++++++++++++++++++++++++--------
drivers/net/enic/enic_res.h | 1
3 files changed, 102 insertions(+), 24 deletions(-)
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index a930fb9..084190e 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -32,7 +32,7 @@
#define DRV_NAME "enic"
#define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver"
-#define DRV_VERSION "1.4.1.8"
+#define DRV_VERSION "1.4.1.9"
#define DRV_COPYRIGHT "Copyright 2008-2010 Cisco Systems, Inc"
#define ENIC_BARS_MAX 6
@@ -78,8 +78,10 @@ struct enic {
spinlock_t devcmd_lock;
u8 mac_addr[ETH_ALEN];
u8 mc_addr[ENIC_MULTICAST_PERFECT_FILTERS][ETH_ALEN];
+ u8 uc_addr[ENIC_UNICAST_PERFECT_FILTERS][ETH_ALEN];
unsigned int flags;
unsigned int mc_count;
+ unsigned int uc_count;
int csum_rx_enabled;
u32 port_mtu;
u32 rx_coalesce_usecs;
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 075ca5f..de7b25c 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -1002,7 +1002,7 @@ static int enic_dev_packet_filter(struct enic *enic, int directed,
return err;
}
-static int enic_dev_add_multicast_addr(struct enic *enic, u8 *addr)
+static int enic_dev_add_addr(struct enic *enic, u8 *addr)
{
int err;
@@ -1013,7 +1013,7 @@ static int enic_dev_add_multicast_addr(struct enic *enic, u8 *addr)
return err;
}
-static int enic_dev_del_multicast_addr(struct enic *enic, u8 *addr)
+static int enic_dev_del_addr(struct enic *enic, u8 *addr)
{
int err;
@@ -1024,29 +1024,19 @@ static int enic_dev_del_multicast_addr(struct enic *enic, u8 *addr)
return err;
}
-/* netif_tx_lock held, BHs disabled */
-static void enic_set_multicast_list(struct net_device *netdev)
+static void enic_add_multicast_addr_list(struct enic *enic)
{
- struct enic *enic = netdev_priv(netdev);
+ struct net_device *netdev = enic->netdev;
struct netdev_hw_addr *ha;
- int directed = 1;
- int multicast = (netdev->flags & IFF_MULTICAST) ? 1 : 0;
- int broadcast = (netdev->flags & IFF_BROADCAST) ? 1 : 0;
- int promisc = (netdev->flags & IFF_PROMISC) ? 1 : 0;
unsigned int mc_count = netdev_mc_count(netdev);
- int allmulti = (netdev->flags & IFF_ALLMULTI) ||
- mc_count > ENIC_MULTICAST_PERFECT_FILTERS;
- unsigned int flags = netdev->flags | (allmulti ? IFF_ALLMULTI : 0);
u8 mc_addr[ENIC_MULTICAST_PERFECT_FILTERS][ETH_ALEN];
unsigned int i, j;
- if (mc_count > ENIC_MULTICAST_PERFECT_FILTERS)
+ if (mc_count > ENIC_MULTICAST_PERFECT_FILTERS) {
+ netdev_warn(netdev, "Registering only %d out of %d "
+ "multicast addresses\n",
+ ENIC_MULTICAST_PERFECT_FILTERS, mc_count);
mc_count = ENIC_MULTICAST_PERFECT_FILTERS;
-
- if (enic->flags != flags) {
- enic->flags = flags;
- enic_dev_packet_filter(enic, directed,
- multicast, broadcast, promisc, allmulti);
}
/* Is there an easier way? Trying to minimize to
@@ -1068,7 +1058,7 @@ static void enic_set_multicast_list(struct net_device *netdev)
mc_addr[j]) == 0)
break;
if (j == mc_count)
- enic_dev_del_multicast_addr(enic, enic->mc_addr[i]);
+ enic_dev_del_addr(enic, enic->mc_addr[i]);
}
for (i = 0; i < mc_count; i++) {
@@ -1077,7 +1067,7 @@ static void enic_set_multicast_list(struct net_device *netdev)
enic->mc_addr[j]) == 0)
break;
if (j == enic->mc_count)
- enic_dev_add_multicast_addr(enic, mc_addr[i]);
+ enic_dev_add_addr(enic, mc_addr[i]);
}
/* Save the list to compare against next time
@@ -1089,6 +1079,89 @@ static void enic_set_multicast_list(struct net_device *netdev)
enic->mc_count = mc_count;
}
+static void enic_add_unicast_addr_list(struct enic *enic)
+{
+ struct net_device *netdev = enic->netdev;
+ struct netdev_hw_addr *ha;
+ unsigned int uc_count = netdev_uc_count(netdev);
+ u8 uc_addr[ENIC_UNICAST_PERFECT_FILTERS][ETH_ALEN];
+ unsigned int i, j;
+
+ if (uc_count > ENIC_UNICAST_PERFECT_FILTERS) {
+ netdev_warn(netdev, "Registering only %d out of %d "
+ "unicast addresses\n",
+ ENIC_UNICAST_PERFECT_FILTERS, uc_count);
+ uc_count = ENIC_UNICAST_PERFECT_FILTERS;
+ }
+
+ /* Is there an easier way? Trying to minimize to
+ * calls to add/del unicast addrs. We keep the
+ * addrs from the last call in enic->uc_addr and
+ * look for changes to add/del.
+ */
+
+ i = 0;
+ netdev_for_each_uc_addr(ha, netdev) {
+ if (i == uc_count)
+ break;
+ memcpy(uc_addr[i++], ha->addr, ETH_ALEN);
+ }
+
+ for (i = 0; i < enic->uc_count; i++) {
+ for (j = 0; j < uc_count; j++)
+ if (compare_ether_addr(enic->uc_addr[i],
+ uc_addr[j]) == 0)
+ break;
+ if (j == uc_count)
+ enic_dev_del_addr(enic, enic->uc_addr[i]);
+ }
+
+ for (i = 0; i < uc_count; i++) {
+ for (j = 0; j < enic->uc_count; j++)
+ if (compare_ether_addr(uc_addr[i],
+ enic->uc_addr[j]) == 0)
+ break;
+ if (j == enic->uc_count)
+ enic_dev_add_addr(enic, uc_addr[i]);
+ }
+
+ /* Save the list to compare against next time
+ */
+
+ for (i = 0; i < uc_count; i++)
+ memcpy(enic->uc_addr[i], uc_addr[i], ETH_ALEN);
+
+ enic->uc_count = uc_count;
+}
+
+/* netif_tx_lock held, BHs disabled */
+static void enic_set_rx_mode(struct net_device *netdev)
+{
+ struct enic *enic = netdev_priv(netdev);
+ int directed = 1;
+ int multicast = (netdev->flags & IFF_MULTICAST) ? 1 : 0;
+ int broadcast = (netdev->flags & IFF_BROADCAST) ? 1 : 0;
+ int promisc = (netdev->flags & IFF_PROMISC) ||
+ netdev_uc_count(netdev) > ENIC_UNICAST_PERFECT_FILTERS;
+ int allmulti = (netdev->flags & IFF_ALLMULTI) ||
+ netdev_mc_count(netdev) > ENIC_MULTICAST_PERFECT_FILTERS;
+ unsigned int flags = netdev->flags |
+ (allmulti ? IFF_ALLMULTI : 0) |
+ (promisc ? IFF_PROMISC : 0);
+
+ if (enic->flags != flags) {
+ enic->flags = flags;
+ enic_dev_packet_filter(enic, directed,
+ multicast, broadcast, promisc, allmulti);
+ }
+
+ if (!promisc) {
+ enic_add_unicast_addr_list(enic);
+ if (!allmulti)
+ enic_add_multicast_addr_list(enic);
+ }
+}
+
/* rtnl lock is held */
static void enic_vlan_rx_register(struct net_device *netdev,
struct vlan_group *vlan_group)
@@ -1852,7 +1925,7 @@ static int enic_open(struct net_device *netdev)
vnic_rq_enable(&enic->rq[i]);
enic_dev_add_station_addr(enic);
- enic_set_multicast_list(netdev);
+ enic_set_rx_mode(netdev);
netif_wake_queue(netdev);
@@ -2328,7 +2401,8 @@ static const struct net_device_ops enic_netdev_dynamic_ops = {
.ndo_start_xmit = enic_hard_start_xmit,
.ndo_get_stats = enic_get_stats,
.ndo_validate_addr = eth_validate_addr,
- .ndo_set_multicast_list = enic_set_multicast_list,
+ .ndo_set_rx_mode = enic_set_rx_mode,
+ .ndo_set_multicast_list = enic_set_rx_mode,
.ndo_set_mac_address = enic_set_mac_address_dynamic,
.ndo_change_mtu = enic_change_mtu,
.ndo_vlan_rx_register = enic_vlan_rx_register,
@@ -2349,7 +2423,8 @@ static const struct net_device_ops enic_netdev_ops = {
.ndo_get_stats = enic_get_stats,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = enic_set_mac_address,
- .ndo_set_multicast_list = enic_set_multicast_list,
+ .ndo_set_rx_mode = enic_set_rx_mode,
+ .ndo_set_multicast_list = enic_set_rx_mode,
.ndo_change_mtu = enic_change_mtu,
.ndo_vlan_rx_register = enic_vlan_rx_register,
.ndo_vlan_rx_add_vid = enic_vlan_rx_add_vid,
diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h
index 9a103d9..25be273 100644
--- a/drivers/net/enic/enic_res.h
+++ b/drivers/net/enic/enic_res.h
@@ -34,6 +34,7 @@
#define ENIC_MAX_MTU 9000
#define ENIC_MULTICAST_PERFECT_FILTERS 32
+#define ENIC_UNICAST_PERFECT_FILTERS 32
#define ENIC_NON_TSO_MAX_DESC 16
^ permalink raw reply related
* Re: [PATCH 2.6.36] vlan: Avoid hwaccel vlan packets when vid not used
From: Eric Dumazet @ 2010-12-05 8:03 UTC (permalink / raw)
To: Michael Leun
Cc: netdev, Jesse Gross, linux-kernel, stable, Ben Greear,
David Miller
In-Reply-To: <20101205030712.36149bc2@xenia.leun.net>
Le dimanche 05 décembre 2010 à 03:07 +0100, Michael Leun a écrit :
> On Wed, 01 Dec 2010 11:55:14 +0100
> Eric Dumazet <eric.dumazet@gmail.com> wrote:
>
> > Le mercredi 01 décembre 2010 à 11:17 +0100, Michael Leun a écrit :
> >
> > > Yup, from what I've tested this works (and tcpdump sees broadcast
> > > packets even for vlans not configured at the moment including vlan
> > > tag
> > > - yipee!).
> > >
>
> This was tested on machine with
> root@tp_z61m:~/src/tcpdump-4.1.1# lspci|grep Eth
> 02:00.0 Ethernet controller: Broadcom Corporation NetXtreme BCM5752M Gigabit Ethernet PCI Express (rev 02)
>
> There it works as I said.
>
> But on
>
> hpdl320g5:/home/ml # lspci | grep Eth
> 03:04.0 Ethernet controller: Broadcom Corporation NetXtreme BCM5714 Gigabit Ethernet (rev a3)
> 03:04.1 Ethernet controller: Broadcom Corporation NetXtreme BCM5714 Gigabit Ethernet (rev a3)
>
> the good message is that it also does not crash, but with tcpdump I see
> vlan tags when no vlan devices configured on the respective eth, if so
> I do not see tags anymore vlan tags on the trunk interface.
>
For all these very specific needs, you'll have to try 2.6.37 I am
afraid. Jesse did huge changes to exactly make this working, we wont
backport this to 2.6.36, but only avoid crashes.
> hpdl320g5:/home/ml # ifconfig -a
> [...]
> eth1 Link encap:Ethernet Hardware Adresse xx:xx:xx:xx:xx:xx
> UP BROADCAST MULTICAST MTU:1500 Metric:1
> RX packets:0 errors:0 dropped:0 overruns:0 frame:0
> TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
> collisions:0 Sendewarteschlangenlänge:1000
> RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
> Interrupt:17
> [...]
>
> hpdl320g5:/home/ml # tcpdump -i eth1 -n -e
> tcpdump: WARNING: eth1: no IPv4 address assigned
> tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
> listening on eth1, link-type EN10MB (Ethernet), capture size 96 bytes
> [...]
> 02:45:57.597640 xx:xx:xx:xx:xx:xx > ff:ff:ff:ff:ff:ff, ethertype 802.1Q (0x8100), length 64: vlan 1505, p 0, ethertype 802.1Q, vlan 99, p 3, ethertype ARP, arp who-has 10.0.0.1 tell 10.0.0.2
> 02:45:57.622654 xx:xx:xx:xx:xx:xx > ff:ff:ff:ff:ff:ff, ethertype 802.1Q (0x8100), length 64: vlan 1505, p 0, ethertype 802.1Q, vlan 99, p 3, ethertype ARP, arp who-has 10.0.0.1 tell 10.0.0.2
> [...]
>
> hpdl320g5:/home/ml # vconfig add eth1 2
> WARNING: Could not open /proc/net/vlan/config. Maybe you need to load the 8021q module, or maybe you are not using PROCFS??
> Added VLAN with VID == 2 to IF -:eth1:-
> hpdl320g5:/home/ml # cat /proc/net/vlan/config
> VLAN Dev name | VLAN ID
> Name-Type: VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD
> eth1.2 | 2 | eth1
> hpdl320g5:/home/ml # tcpdump -i eth1 -n -e
> tcpdump: WARNING: eth1: no IPv4 address assigned
> tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
> listening on eth1, link-type EN10MB (Ethernet), capture size 96 bytes
> [...]
> 02:50:18.095959 xx:xx:xx:xx:xx:xx > ff:ff:ff:ff:ff:ff, ethertype 802.1Q (0x8100), length 60: vlan 99, p 3, ethertype ARP, arp who-has 10.0.0.1 tell 10.0.0.2
> 02:50:18.120989 xx:xx:xx:xx:xx:xx > ff:ff:ff:ff:ff:ff, ethertype 802.1Q (0x8100), length 60: vlan 99, p 3, ethertype ARP, arp who-has 10.0.0.1 tell 10.0.0.2
> [...]
>
> The same packages we saw double vlan tagged a few minutes ago now appear single vlan tagged (and of course, other packets that were shown single vlan tagged before are now shown without vlan tag / eth type 0x0800).
>
>
> On the other machine:
>
> root@tp_z61m:~# cat /proc/net/vlan/config
> VLAN Dev name | VLAN ID
> Name-Type: VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD
> eth0.741 | 741 | eth0
> eth0.2 | 2 | eth0
> root@tp_z61m:~/src/tcpdump-4.1.1# ./tcpdump -i eth0 -n -e not port 22
> tcpdump: WARNING: eth0: no IPv4 address assigned
> tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
> listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
> 03:06:51.859016 xx:xx:xx:xx:xx:xx > ff:ff:ff:ff:ff:ff, ethertype 802.1Q (0x8100), length 64: vlan 1505, p 0, ethertype 802.1Q, vlan 99, p 3, ethertype ARP, Request who-has 10.0.0.1 tell 10.0.0.2, length 42
> 03:06:51.883956 xx:xx:xx:xx:xx:xx > ff:ff:ff:ff:ff:ff, ethertype 802.1Q (0x8100), length 64: vlan 1505, p 0, ethertype 802.1Q, vlan 99, p 3, ethertype ARP, Request who-has 10.0.0.1 tell 10.0.0.2, length 42
>
>
>
> [...]
> > Here is the revised patch again then for stable team, via David Miller
> > agreement.
> [...]
>
_______________________________________________
stable mailing list
stable@linux.kernel.org
http://linux.kernel.org/mailman/listinfo/stable
^ permalink raw reply
* Re: [PATCH 3/5] NET: IPV4: ARP: allow to invalidate specific ARP entries
From: Eric Dumazet @ 2010-12-05 8:19 UTC (permalink / raw)
To: Maxim Levitsky
Cc: linux1394-devel, Stefan Richter, netdev, David S. Miller,
Alexey Kuznetsov, James Morris, Patrick McHardy
In-Reply-To: <1291504514.1874.92.camel@maxim-laptop>
Le dimanche 05 décembre 2010 à 01:15 +0200, Maxim Levitsky a écrit :
> On Mon, 2010-11-29 at 04:09 +0200, Maxim Levitsky wrote:
> > IPv4 over firewire needs to be able to remove ARP entries
> > from the ARP cache that belong to nodes that are removed, because
> > IPv4 over firewire uses ARP packets for private information
> > about nodes.
> >
> > This information becomes invalid as soon as node drops
> > off the bus and when it reconnects, its only possible
> > to start takling to is after it responded to an ARP packet.
> > But ARP cache prevents such packets from being sent.
> >
> > CC: netdev@vger.kernel.org
> > CC: "David S. Miller" <davem@davemloft.net>
> > CC: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
> > CC: James Morris <jmorris@namei.org>
> > CC: Patrick McHardy <kaber@trash.net>
>
> Anybody?
>
> Best regards,
> Maxim Levitsky
> >
> >
> > Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
> > ---
> > include/net/arp.h | 1 +
> > net/ipv4/arp.c | 29 ++++++++++++++++++-----------
> > 2 files changed, 19 insertions(+), 11 deletions(-)
> >
> > diff --git a/include/net/arp.h b/include/net/arp.h
> > index f4cf6ce..91f0568 100644
> > --- a/include/net/arp.h
> > +++ b/include/net/arp.h
> > @@ -25,5 +25,6 @@ extern struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
> > const unsigned char *src_hw,
> > const unsigned char *target_hw);
> > extern void arp_xmit(struct sk_buff *skb);
> > +int arp_invalidate(struct net_device *dev, __be32 ip);
> >
> > #endif /* _ARP_H */
> > diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
> > index d8e540c..35b1272 100644
> > --- a/net/ipv4/arp.c
> > +++ b/net/ipv4/arp.c
> > @@ -1142,6 +1142,23 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev)
> > return err;
> > }
> >
> > +int arp_invalidate(struct net_device *dev, __be32 ip)
> > +{
> > + int err = -ENXIO;
> > + struct neighbour *neigh = neigh_lookup(&arp_tbl, &ip, dev);
> > +
> > + if (neigh) {
> > + if (neigh->nud_state & ~NUD_NOARP)
> > + err = neigh_update(neigh, NULL, NUD_FAILED,
> > + NEIGH_UPDATE_F_OVERRIDE|
> > + NEIGH_UPDATE_F_ADMIN);
> > + neigh_release(neigh);
> > + }
> > +
> > + return err;
> > +}
> > +EXPORT_SYMBOL(arp_invalidate);
> > +
> > static int arp_req_delete_public(struct net *net, struct arpreq *r,
> > struct net_device *dev)
> > {
> > @@ -1162,7 +1179,6 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
> > {
> > int err;
> > __be32 ip;
> > - struct neighbour *neigh;
> >
> > if (r->arp_flags & ATF_PUBL)
> > return arp_req_delete_public(net, r, dev);
> > @@ -1180,16 +1196,7 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
> > if (!dev)
> > return -EINVAL;
> > }
> > - err = -ENXIO;
> > - neigh = neigh_lookup(&arp_tbl, &ip, dev);
> > - if (neigh) {
> > - if (neigh->nud_state & ~NUD_NOARP)
> > - err = neigh_update(neigh, NULL, NUD_FAILED,
> > - NEIGH_UPDATE_F_OVERRIDE|
> > - NEIGH_UPDATE_F_ADMIN);
> > - neigh_release(neigh);
> > - }
> > - return err;
> > + return arp_invalidate(dev, ip);
> > }
> >
> > /*
>
Hmm..
If somebody can explain why RTNL is held in arp_ioctl() (and therefore
in arp_req_delete()), we might first remove RTNL use in arp_ioctl() so
that your patch can be applied.
Right now it is not good, because RTNL wont be necessarly held when you
are going to call arp_invalidate() ?
^ permalink raw reply
* Re: [PATCH 2.6.36] vlan: Avoid hwaccel vlan packets when vid not used
From: Michael Leun @ 2010-12-05 9:55 UTC (permalink / raw)
To: Eric Dumazet
Cc: David Miller, Ben Greear, linux-kernel, netdev, Jesse Gross,
stable
In-Reply-To: <1291536233.2806.102.camel@edumazet-laptop>
On Sun, 05 Dec 2010 09:03:53 +0100
Eric Dumazet <eric.dumazet@gmail.com> wrote:
> > But on
> >
> > hpdl320g5:/home/ml # lspci | grep Eth
> > 03:04.0 Ethernet controller: Broadcom Corporation NetXtreme BCM5714
> > Gigabit Ethernet (rev a3) 03:04.1 Ethernet controller: Broadcom
> > Corporation NetXtreme BCM5714 Gigabit Ethernet (rev a3)
> >
> > the good message is that it also does not crash, but with tcpdump I
> > see vlan tags when no vlan devices configured on the respective
> > eth, if so I do not see tags anymore vlan tags on the trunk
> > interface.
> >
>
> For all these very specific needs, you'll have to try 2.6.37 I am
> afraid. Jesse did huge changes to exactly make this working, we wont
> backport this to 2.6.36, but only avoid crashes.
OK, I'm perfectly fine with that, of course, actually nice to hear that
the issue already is addressed.
Likely I'll give some rc an shot on this machine (maybe over christmas),
but it is an production machine (acutally testing other devices is the
"product" produced on this machine), so unfortunately I'm not that free
in when and what I can do (but the possibility to, for example, bridge
the trunk interface would make testing easier, that justifies
something...).
Thank you all very much for your work.
--
MfG,
Michael Leun
^ permalink raw reply
* Re: Question about __alloc_skb() speedup
From: Junchang Wang @ 2010-12-05 10:56 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev
In-Reply-To: <1291474058.2806.96.camel@edumazet-laptop>
On Sat, Dec 04, 2010 at 03:47:38PM +0100, Eric Dumazet wrote:
>
>Yes I believe so, pktgen being very specific, but I have few questions :
>
>Is it with SLUB or SLAB ?
I had read your discussion about "net: allocate skbs on local node" in
the list, so SLUB was used.
BTW, what I observed is that network subsystem scales well on NUMA
systems equipped with a single processor(up to six cores), but the
performance didn't scale very well if there are two processors.
I have noticed there are a number of discussions in the list. Are
there any suggestions? I'm very pleasant to do test.
>
>How many buffers in TX ring on you nic (ethtool -g eth0) ?
>
Pre-set maximums:
RX: 4096
RX Mini: 0
RX Jumbo: 0
TX: 4096
Current hardware settings:
RX: 512
RX Mini: 0
RX Jumbo: 0
TX: 512
>What is the datalen value here ? (you prefetch, then advance skb->data)
>
16. But the following skb_push will drawback 14 bytes.
>32 or 64bit kernel ?
>
This is a CentOS 5.5 - 64bit distribution with the latest net-next.
>How many pps do you get before and after patch ?
>
A Intel SR1625 server with two E5530 quad-core processors and a single
ixgbe-based NIC.
Without prefetch: 8.63 Mpps
With prefetch: 9.03 Mpps
Improvement: 4.6%
Thanks.
--Junchang
^ permalink raw reply
* [PATCH] net: RCU conversion of dev_getbyhwaddr() and arp_ioctl()
From: Eric Dumazet @ 2010-12-05 11:23 UTC (permalink / raw)
To: Maxim Levitsky
Cc: linux1394-devel, Stefan Richter, netdev, David S. Miller,
Alexey Kuznetsov, James Morris, Patrick McHardy
In-Reply-To: <1291537161.2806.109.camel@edumazet-laptop>
Le dimanche 05 décembre 2010 à 09:19 +0100, Eric Dumazet a écrit :
> Hmm..
>
> If somebody can explain why RTNL is held in arp_ioctl() (and therefore
> in arp_req_delete()), we might first remove RTNL use in arp_ioctl() so
> that your patch can be applied.
>
> Right now it is not good, because RTNL wont be necessarly held when you
> are going to call arp_invalidate() ?
While doing this analysis, I found a refcount bug in llc, I'll send a
patch for net-2.6
Meanwhile, here is the patch for net-next-2.6
Your patch then can be applied after mine.
Thanks
[PATCH] net: RCU conversion of dev_getbyhwaddr() and arp_ioctl()
dev_getbyhwaddr() was called under RTNL.
Rename it to dev_getbyhwaddr_rcu() and change all its caller to now use
RCU locking instead of RTNL.
Change arp_ioctl() to use RCU instead of RTNL locking.
Note: this fix a dev refcount bug in llc
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
include/linux/netdevice.h | 3 ++-
net/core/dev.c | 17 +++++++----------
net/ieee802154/af_ieee802154.c | 6 +++---
net/ipv4/arp.c | 17 +++++++++--------
net/llc/af_llc.c | 11 ++++++-----
5 files changed, 27 insertions(+), 27 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index a9ac5dc..d31bc3c 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1360,7 +1360,8 @@ static inline struct net_device *first_net_device(struct net *net)
extern int netdev_boot_setup_check(struct net_device *dev);
extern unsigned long netdev_boot_base(const char *prefix, int unit);
-extern struct net_device *dev_getbyhwaddr(struct net *net, unsigned short type, char *hwaddr);
+extern struct net_device *dev_getbyhwaddr_rcu(struct net *net, unsigned short type,
+ const char *hwaddr);
extern struct net_device *dev_getfirstbyhwtype(struct net *net, unsigned short type);
extern struct net_device *__dev_getfirstbyhwtype(struct net *net, unsigned short type);
extern void dev_add_pack(struct packet_type *pt);
diff --git a/net/core/dev.c b/net/core/dev.c
index cd24374..8630142 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -743,34 +743,31 @@ struct net_device *dev_get_by_index(struct net *net, int ifindex)
EXPORT_SYMBOL(dev_get_by_index);
/**
- * dev_getbyhwaddr - find a device by its hardware address
+ * dev_getbyhwaddr_rcu - find a device by its hardware address
* @net: the applicable net namespace
* @type: media type of device
* @ha: hardware address
*
* Search for an interface by MAC address. Returns NULL if the device
- * is not found or a pointer to the device. The caller must hold the
- * rtnl semaphore. The returned device has not had its ref count increased
+ * is not found or a pointer to the device. The caller must hold RCU
+ * The returned device has not had its ref count increased
* and the caller must therefore be careful about locking
*
- * BUGS:
- * If the API was consistent this would be __dev_get_by_hwaddr
*/
-struct net_device *dev_getbyhwaddr(struct net *net, unsigned short type, char *ha)
+struct net_device *dev_getbyhwaddr_rcu(struct net *net, unsigned short type,
+ const char *ha)
{
struct net_device *dev;
- ASSERT_RTNL();
-
- for_each_netdev(net, dev)
+ for_each_netdev_rcu(net, dev)
if (dev->type == type &&
!memcmp(dev->dev_addr, ha, dev->addr_len))
return dev;
return NULL;
}
-EXPORT_SYMBOL(dev_getbyhwaddr);
+EXPORT_SYMBOL(dev_getbyhwaddr_rcu);
struct net_device *__dev_getfirstbyhwtype(struct net *net, unsigned short type)
{
diff --git a/net/ieee802154/af_ieee802154.c b/net/ieee802154/af_ieee802154.c
index 93c91b6..6df6ecf 100644
--- a/net/ieee802154/af_ieee802154.c
+++ b/net/ieee802154/af_ieee802154.c
@@ -52,11 +52,11 @@ struct net_device *ieee802154_get_dev(struct net *net,
switch (addr->addr_type) {
case IEEE802154_ADDR_LONG:
- rtnl_lock();
- dev = dev_getbyhwaddr(net, ARPHRD_IEEE802154, addr->hwaddr);
+ rcu_read_lock();
+ dev = dev_getbyhwaddr_rcu(net, ARPHRD_IEEE802154, addr->hwaddr);
if (dev)
dev_hold(dev);
- rtnl_unlock();
+ rcu_read_unlock();
break;
case IEEE802154_ADDR_SHORT:
if (addr->pan_id == 0xffff ||
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 7833f17..ec0966f 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -1017,13 +1017,14 @@ static int arp_req_set_proxy(struct net *net, struct net_device *dev, int on)
IPV4_DEVCONF_ALL(net, PROXY_ARP) = on;
return 0;
}
- if (__in_dev_get_rtnl(dev)) {
- IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), PROXY_ARP, on);
+ if (__in_dev_get_rcu(dev)) {
+ IN_DEV_CONF_SET(__in_dev_get_rcu(dev), PROXY_ARP, on);
return 0;
}
return -ENXIO;
}
+/* must be called with rcu_read_lock() */
static int arp_req_set_public(struct net *net, struct arpreq *r,
struct net_device *dev)
{
@@ -1033,7 +1034,7 @@ static int arp_req_set_public(struct net *net, struct arpreq *r,
if (mask && mask != htonl(0xFFFFFFFF))
return -EINVAL;
if (!dev && (r->arp_flags & ATF_COM)) {
- dev = dev_getbyhwaddr(net, r->arp_ha.sa_family,
+ dev = dev_getbyhwaddr_rcu(net, r->arp_ha.sa_family,
r->arp_ha.sa_data);
if (!dev)
return -ENODEV;
@@ -1225,10 +1226,10 @@ int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg)
if (!(r.arp_flags & ATF_NETMASK))
((struct sockaddr_in *)&r.arp_netmask)->sin_addr.s_addr =
htonl(0xFFFFFFFFUL);
- rtnl_lock();
+ rcu_read_lock();
if (r.arp_dev[0]) {
err = -ENODEV;
- dev = __dev_get_by_name(net, r.arp_dev);
+ dev = dev_get_by_name_rcu(net, r.arp_dev);
if (dev == NULL)
goto out;
@@ -1252,12 +1253,12 @@ int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg)
break;
case SIOCGARP:
err = arp_req_get(&r, dev);
- if (!err && copy_to_user(arg, &r, sizeof(r)))
- err = -EFAULT;
break;
}
out:
- rtnl_unlock();
+ rcu_read_unlock();
+ if (cmd == SIOCGARP && !err && copy_to_user(arg, &r, sizeof(r)))
+ err = -EFAULT;
return err;
}
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index 5826129..dfd3a64 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -316,9 +316,9 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
if (unlikely(addr->sllc_family != AF_LLC))
goto out;
rc = -ENODEV;
- rtnl_lock();
+ rcu_read_lock();
if (sk->sk_bound_dev_if) {
- llc->dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if);
+ llc->dev = dev_get_by_index_rcu(&init_net, sk->sk_bound_dev_if);
if (llc->dev) {
if (!addr->sllc_arphrd)
addr->sllc_arphrd = llc->dev->type;
@@ -329,14 +329,15 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
!llc_mac_match(addr->sllc_mac,
llc->dev->dev_addr)) {
rc = -EINVAL;
- dev_put(llc->dev);
llc->dev = NULL;
}
}
} else
- llc->dev = dev_getbyhwaddr(&init_net, addr->sllc_arphrd,
+ llc->dev = dev_getbyhwaddr_rcu(&init_net, addr->sllc_arphrd,
addr->sllc_mac);
- rtnl_unlock();
+ if (llc->dev)
+ dev_hold(llc->dev);
+ rcu_read_unlock();
if (!llc->dev)
goto out;
if (!addr->sllc_sap) {
^ permalink raw reply related
* [PATCH net-2.6] llc: fix a device refcount imbalance
From: Eric Dumazet @ 2010-12-05 12:03 UTC (permalink / raw)
To: Maxim Levitsky, David Miller
Cc: linux1394-devel, Stefan Richter, netdev, Alexey Kuznetsov,
James Morris, Patrick McHardy, Octavian Purdila, stable
In-Reply-To: <1291548233.2806.212.camel@edumazet-laptop>
Le dimanche 05 décembre 2010 à 12:23 +0100, Eric Dumazet a écrit :
> Le dimanche 05 décembre 2010 à 09:19 +0100, Eric Dumazet a écrit :
>
> > Hmm..
> >
> > If somebody can explain why RTNL is held in arp_ioctl() (and therefore
> > in arp_req_delete()), we might first remove RTNL use in arp_ioctl() so
> > that your patch can be applied.
> >
> > Right now it is not good, because RTNL wont be necessarly held when you
> > are going to call arp_invalidate() ?
>
> While doing this analysis, I found a refcount bug in llc, I'll send a
> patch for net-2.6
Oh well, of course I must first fix the bug in net-2.6, and wait David
pull the fix in net-next-2.6 before sending this rcu conversion.
Note: this patch should be sent to stable teams (2.6.34 and up)
[PATCH net-2.6] llc: fix a device refcount imbalance
commit abf9d537fea225 (llc: add support for SO_BINDTODEVICE) added one
refcount imbalance in llc_ui_bind(), because dev_getbyhwaddr() doesnt
take a reference on device, while dev_get_by_index() does.
Fix this using RCU locking. And since an RCU conversion will be done for
2.6.38 for dev_getbyhwaddr(), put the rcu_read_lock/unlock exactly at
their final place.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Cc: stable@kernel.org
Cc: Octavian Purdila <opurdila@ixiacom.com>
---
net/llc/af_llc.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index 5826129..e35dbe5 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -317,8 +317,9 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
goto out;
rc = -ENODEV;
rtnl_lock();
+ rcu_read_lock();
if (sk->sk_bound_dev_if) {
- llc->dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if);
+ llc->dev = dev_get_by_index_rcu(&init_net, sk->sk_bound_dev_if);
if (llc->dev) {
if (!addr->sllc_arphrd)
addr->sllc_arphrd = llc->dev->type;
@@ -329,13 +330,13 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
!llc_mac_match(addr->sllc_mac,
llc->dev->dev_addr)) {
rc = -EINVAL;
- dev_put(llc->dev);
llc->dev = NULL;
}
}
} else
llc->dev = dev_getbyhwaddr(&init_net, addr->sllc_arphrd,
addr->sllc_mac);
+ rcu_read_unlock();
rtnl_unlock();
if (!llc->dev)
goto out;
^ permalink raw reply related
* Re: kernel panic with time-stamping in phy devices (monitor mode)
From: Eric Dumazet @ 2010-12-05 12:24 UTC (permalink / raw)
To: Andrew Watts; +Cc: Richard Cochran, netdev, David Miller, stable
In-Reply-To: <906429.41845.qm@web111015.mail.gq1.yahoo.com>
Le samedi 04 décembre 2010 à 12:46 -0800, Andrew Watts a écrit :
> Eric, I echo the thanks on the lightning patch.
> Impressive turnaround!
>
> There's an open bug report on the kernel's bugzilla
> for 2.6.36 (#24102). What is the best way to tie these
> together?
Thanks Andy, here is the official patch submission I am going to make.
[PATCH net-2.6] net: fix skb_defer_rx_timestamp()
After commit c1f19b51d1d8 (net: support time stamping in phy devices.),
kernel might crash if CONFIG_NETWORK_PHY_TIMESTAMPING=y and
skb_defer_rx_timestamp() handles a packet without an ethernet header.
Fixes kernel bugzilla #24102
Reference: https://bugzilla.kernel.org/show_bug.cgi?id=24102
Reported-and-tested-by: Andrew Watts <akwatts@ymail.com>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: stable@kernel.org
---
net/core/timestamping.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/net/core/timestamping.c b/net/core/timestamping.c
index 0ae6c22..c4fbf85 100644
--- a/net/core/timestamping.c
+++ b/net/core/timestamping.c
@@ -96,11 +96,13 @@ bool skb_defer_rx_timestamp(struct sk_buff *skb)
struct phy_device *phydev;
unsigned int type;
- skb_push(skb, ETH_HLEN);
+ if (skb->data - ETH_HLEN < skb->head)
+ return false;
+ __skb_push(skb, ETH_HLEN);
type = classify(skb);
- skb_pull(skb, ETH_HLEN);
+ __skb_pull(skb, ETH_HLEN);
switch (type) {
case PTP_CLASS_V1_IPV4:
^ permalink raw reply related
* Re: [PATCH net-2.6] ifb: goto resched directly if error happens and dp->tq isn't empty
From: jamal @ 2010-12-05 14:25 UTC (permalink / raw)
To: Changli Gao; +Cc: David S. Miller, Jarek Poplawski, netdev
In-Reply-To: <1291507748-4958-1-git-send-email-xiaosuo@gmail.com>
On Sun, 2010-12-05 at 08:09 +0800, Changli Gao wrote:
> If we break the loop when there are still skbs in tq and no skb in
> rq, the skbs will be left in txq until new skbs are enqueued into rq.
> In rare cases, no new skb is queued, then these skbs will stay in rq
> forever.
>
> After this patch, if tq isn't empty when we break the loop, we goto
> resched directly.
>
> Signed-off-by: Changli Gao <xiaosuo@gmail.com>
Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
Dave, this goes to stable as well.
cheers,
jamal
^ permalink raw reply
* Re: [PATCH 3/3 v2] ifb: use the lockless variants of skb_queue
From: jamal @ 2010-12-05 14:26 UTC (permalink / raw)
To: Changli Gao; +Cc: netdev, Jarek Poplawski
In-Reply-To: <1291510912-6979-1-git-send-email-xiaosuo@gmail.com>
On Sun, 2010-12-05 at 09:01 +0800, Changli Gao wrote:
> rq and tq are both protected by tx queue lock, so we can simply use
> the lockless variants of skb_queue.
>
> skb_queue_splice_tail_init() is used instead of the open coded and slow
> one.
>
> Signed-off-by: Changli Gao <xiaosuo@gmail.com>
Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
cheers,
jamal
^ permalink raw reply
* Re: [PATCH 3/3] ifb: move tq from ifb_private
From: jamal @ 2010-12-05 14:27 UTC (permalink / raw)
To: Changli Gao; +Cc: Jarek Poplawski, netdev
In-Reply-To: <AANLkTimnejoONxGqusiYVWOKbcy2yqbpFH-XyzgG0=87@mail.gmail.com>
On Sun, 2010-12-05 at 08:22 +0800, Changli Gao wrote:
> On Sun, Dec 5, 2010 at 12:56 AM, Jarek Poplawski <jarkao2@gmail.com> wrote:
> >
> > I'm simply not convinced this kind of (fast) throttling can properly
> > fix any of the problems (what about other flows in the queue), while
> > Changli's patch makes this tasklet simpler and a bit faster.
> >
>
> The error case handled currently is the original netdev disappears but
> the corresponding skbs are still in ifb.
>
> I do also think checking the return value of netif_rx() and
> dev_queue_xmit() can fix more 'problems'. :)
Please proceed with a patch for that as well..
cheers,
jamal
PS:- We forgot to thank Jarek for pointing out the bug.
^ permalink raw reply
* Re: [PATCH 3/3] ifb: move tq from ifb_private
From: jamal @ 2010-12-05 14:30 UTC (permalink / raw)
To: Changli Gao; +Cc: Jarek Poplawski, netdev
In-Reply-To: <AANLkTimMvb187gOFzZZgWuzWJkk_Z3AOZaoc6M76H-e=@mail.gmail.com>
On Sun, 2010-12-05 at 09:13 +0800, Changli Gao wrote:
> BTW: My ultimate goal is making ifb a multi-queue NIC, and the number
> of queues is equal to the number of the possible CPUs.
My view is this is going to be tricky because:
- we use tasklets. When we reschedule we can end up on a differrent
cpu.
-I dont see any point in having a separate softIRQ
- and if you do use other mechanisms it would require a lot more
testing since there are quiet a few use cases of ifb
cheers,
jamal
^ permalink raw reply
* Re: [PATCH 3/3] ifb: move tq from ifb_private
From: Changli Gao @ 2010-12-05 14:40 UTC (permalink / raw)
To: hadi; +Cc: Jarek Poplawski, netdev
In-Reply-To: <1291559402.2159.687.camel@mojatatu>
[-- Attachment #1: Type: text/plain, Size: 800 bytes --]
On Sun, Dec 5, 2010 at 10:30 PM, jamal <hadi@cyberus.ca> wrote:
> On Sun, 2010-12-05 at 09:13 +0800, Changli Gao wrote:
>
>> BTW: My ultimate goal is making ifb a multi-queue NIC, and the number
>> of queues is equal to the number of the possible CPUs.
>
>
> My view is this is going to be tricky because:
> - we use tasklets. When we reschedule we can end up on a differrent
> cpu.
The tasklets always been scheduled to the current CPU unless it has
been schedule already on the other CPU.
> -I dont see any point in having a separate softIRQ
> - and if you do use other mechanisms it would require a lot more
> testing since there are quiet a few use cases of ifb
>
I keep using tasklet. The attachment is the alpha version.
--
Regards,
Changli Gao(xiaosuo@gmail.com)
[-- Attachment #2: ifb.c --]
[-- Type: text/x-csrc, Size: 7698 bytes --]
/* drivers/net/ifb.c:
The purpose of this driver is to provide a device that allows
for sharing of resources:
1) qdiscs/policies that are per device as opposed to system wide.
ifb allows for a device which can be redirected to thus providing
an impression of sharing.
2) Allows for queueing incoming traffic for shaping instead of
dropping.
The original concept is based on what is known as the IMQ
driver initially written by Martin Devera, later rewritten
by Patrick McHardy and then maintained by Andre Correa.
You need the tc action mirror or redirect to feed this device
packets.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version
2 of the License, or (at your option) any later version.
Authors: Jamal Hadi Salim (2005)
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/init.h>
#include <linux/moduleparam.h>
#include <net/pkt_sched.h>
#include <net/net_namespace.h>
#define TX_Q_LIMIT 32
struct ifb_q_private {
struct tasklet_struct ifb_tasklet;
struct sk_buff_head rq;
struct u64_stats_sync syncp;
u64 rx_packets;
u64 rx_bytes;
u64 rx_dropped;
};
struct ifb_private {
struct ifb_q_private __percpu *q;
};
static int numifbs = 2;
static void ri_tasklet(unsigned long _dev)
{
struct net_device *dev = (struct net_device *)_dev;
struct ifb_private *p = netdev_priv(dev);
struct ifb_q_private *qp;
struct netdev_queue *txq;
struct sk_buff *skb;
struct sk_buff_head tq;
__skb_queue_head_init(&tq);
txq = netdev_get_tx_queue(dev, raw_smp_processor_id());
qp = per_cpu_ptr(p->q, raw_smp_processor_id());
if (!__netif_tx_trylock(txq)) {
tasklet_schedule(&qp->ifb_tasklet);
return;
}
skb_queue_splice_tail_init(&qp->rq, &tq);
if (netif_tx_queue_stopped(txq))
netif_tx_wake_queue(txq);
__netif_tx_unlock(txq);
while ((skb = __skb_dequeue(&tq)) != NULL) {
u32 from = G_TC_FROM(skb->tc_verd);
skb->tc_verd = 0;
skb->tc_verd = SET_TC_NCLS(skb->tc_verd);
u64_stats_update_begin(&qp->syncp);
txq->tx_packets++;
txq->tx_bytes += skb->len;
rcu_read_lock();
skb->dev = dev_get_by_index_rcu(&init_net, skb->skb_iif);
if (!skb->dev) {
rcu_read_unlock();
txq->tx_dropped++;
u64_stats_update_end(&qp->syncp);
dev_kfree_skb(skb);
continue;
}
rcu_read_unlock();
u64_stats_update_end(&qp->syncp);
skb->skb_iif = dev->ifindex;
if (from & AT_EGRESS) {
dev_queue_xmit(skb);
} else if (from & AT_INGRESS) {
skb_pull(skb, skb->dev->hard_header_len);
netif_rx(skb);
} else
BUG();
}
}
static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct ifb_private *p = netdev_priv(dev);
struct ifb_q_private *qp = per_cpu_ptr(p->q,
skb_get_queue_mapping(skb));
u32 from = G_TC_FROM(skb->tc_verd);
u64_stats_update_begin(&qp->syncp);
qp->rx_packets++;
qp->rx_bytes += skb->len;
if (!(from & (AT_INGRESS|AT_EGRESS)) || !skb->skb_iif) {
qp->rx_dropped++;
u64_stats_update_end(&qp->syncp);
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
u64_stats_update_end(&qp->syncp);
__skb_queue_tail(&qp->rq, skb);
if (skb_queue_len(&qp->rq) == 1)
tasklet_schedule(&qp->ifb_tasklet);
if (skb_queue_len(&qp->rq) >= dev->tx_queue_len)
netif_stop_queue(dev);
return NETDEV_TX_OK;
}
static int ifb_close(struct net_device *dev)
{
struct ifb_private *p = netdev_priv(dev);
struct ifb_q_private *qp;
int cpu;
for_each_possible_cpu(cpu) {
qp = per_cpu_ptr(p->q, cpu);
tasklet_kill(&qp->ifb_tasklet);
netif_tx_stop_queue(netdev_get_tx_queue(dev, cpu));
__skb_queue_purge(&qp->rq);
}
return 0;
}
static int ifb_open(struct net_device *dev)
{
int cpu;
for_each_possible_cpu(cpu)
netif_tx_start_queue(netdev_get_tx_queue(dev, cpu));
return 0;
}
static int ifb_init(struct net_device *dev)
{
struct ifb_private *p = netdev_priv(dev);
struct ifb_q_private *q;
int cpu;
p->q = alloc_percpu(struct ifb_q_private);
if (!p->q)
return -ENOMEM;
for_each_possible_cpu(cpu) {
q = per_cpu_ptr(p->q, cpu);
tasklet_init(&q->ifb_tasklet, ri_tasklet, (unsigned long)dev);
__skb_queue_head_init(&q->rq);
}
return 0;
}
static void ifb_uninit(struct net_device *dev)
{
struct ifb_private *p = netdev_priv(dev);
free_percpu(p->q);
}
static u16 ifb_select_queue(struct net_device *dev, struct sk_buff *skb)
{
return smp_processor_id();
}
static struct rtnl_link_stats64 *ifb_get_stats64(struct net_device *dev,
struct rtnl_link_stats64 *stats)
{
struct ifb_private *p = netdev_priv(dev);
struct ifb_q_private *q;
struct netdev_queue *txq;
int cpu;
u64 rx_packets, rx_bytes, rx_dropped;
u64 tx_packets, tx_bytes, tx_dropped;
unsigned int start;
for_each_possible_cpu(cpu) {
q = per_cpu_ptr(p->q, cpu);
txq = netdev_get_tx_queue(dev, cpu);
do {
start = u64_stats_fetch_begin_bh(&q->syncp);
rx_packets = q->rx_packets;
rx_bytes = q->rx_bytes;
rx_dropped = q->rx_dropped;
tx_packets = txq->tx_packets;
tx_bytes = txq->tx_bytes;
tx_dropped = txq->tx_dropped;
} while (u64_stats_fetch_retry_bh(&q->syncp, start));
stats->rx_packets += rx_packets;
stats->rx_bytes += rx_bytes;
stats->rx_dropped += rx_dropped;
stats->tx_packets += tx_packets;
stats->tx_bytes += tx_bytes;
stats->tx_dropped += tx_dropped;
}
return stats;
}
static const struct net_device_ops ifb_netdev_ops = {
.ndo_init = ifb_init,
.ndo_uninit = ifb_uninit,
.ndo_open = ifb_open,
.ndo_stop = ifb_close,
.ndo_start_xmit = ifb_xmit,
.ndo_validate_addr = eth_validate_addr,
.ndo_select_queue = ifb_select_queue,
.ndo_get_stats64 = ifb_get_stats64,
};
static void ifb_setup(struct net_device *dev)
{
/* Initialize the device structure. */
dev->destructor = free_netdev;
dev->netdev_ops = &ifb_netdev_ops;
/* Fill in device structure with ethernet-generic values. */
ether_setup(dev);
dev->tx_queue_len = TX_Q_LIMIT;
dev->flags |= IFF_NOARP;
dev->flags &= ~IFF_MULTICAST;
dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
random_ether_addr(dev->dev_addr);
}
static int ifb_validate(struct nlattr *tb[], struct nlattr *data[])
{
if (tb[IFLA_ADDRESS]) {
if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
return -EINVAL;
if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
return -EADDRNOTAVAIL;
}
return 0;
}
static struct rtnl_link_ops ifb_link_ops __read_mostly = {
.kind = "ifb",
.priv_size = sizeof(struct ifb_private),
.setup = ifb_setup,
.validate = ifb_validate,
};
/* Number of ifb devices to be set up by this module. */
module_param(numifbs, int, 0);
MODULE_PARM_DESC(numifbs, "Number of ifb devices");
static int __init ifb_init_one(int index)
{
struct net_device *dev_ifb;
int err;
dev_ifb = alloc_netdev_mq(sizeof(struct ifb_private), "ifb%d",
ifb_setup, num_possible_cpus());
if (!dev_ifb)
return -ENOMEM;
err = dev_alloc_name(dev_ifb, dev_ifb->name);
if (err < 0)
goto err;
dev_ifb->rtnl_link_ops = &ifb_link_ops;
err = register_netdevice(dev_ifb);
if (err < 0)
goto err;
return 0;
err:
free_netdev(dev_ifb);
return err;
}
static int __init ifb_init_module(void)
{
int i, err;
rtnl_lock();
err = __rtnl_link_register(&ifb_link_ops);
for (i = 0; i < numifbs && !err; i++)
err = ifb_init_one(i);
if (err)
__rtnl_link_unregister(&ifb_link_ops);
rtnl_unlock();
return err;
}
static void __exit ifb_cleanup_module(void)
{
rtnl_link_unregister(&ifb_link_ops);
}
module_init(ifb_init_module);
module_exit(ifb_cleanup_module);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jamal Hadi Salim");
MODULE_ALIAS_RTNL_LINK("ifb");
^ permalink raw reply
* Re: [PATCH 3/3] ifb: move tq from ifb_private
From: Eric Dumazet @ 2010-12-05 15:13 UTC (permalink / raw)
To: Changli Gao; +Cc: hadi, Jarek Poplawski, netdev
In-Reply-To: <AANLkTimXDTTNcrFPngzEuoDGVgojtBxUZQPOMiSA7yNw@mail.gmail.com>
Le dimanche 05 décembre 2010 à 22:40 +0800, Changli Gao a écrit :
> On Sun, Dec 5, 2010 at 10:30 PM, jamal <hadi@cyberus.ca> wrote:
> > On Sun, 2010-12-05 at 09:13 +0800, Changli Gao wrote:
> >
> >> BTW: My ultimate goal is making ifb a multi-queue NIC, and the number
> >> of queues is equal to the number of the possible CPUs.
> >
> >
> > My view is this is going to be tricky because:
> > - we use tasklets. When we reschedule we can end up on a differrent
> > cpu.
>
> The tasklets always been scheduled to the current CPU unless it has
> been schedule already on the other CPU.
>
> > -I dont see any point in having a separate softIRQ
> > - and if you do use other mechanisms it would require a lot more
> > testing since there are quiet a few use cases of ifb
> >
>
> I keep using tasklet. The attachment is the alpha version.
>
for_each_possible_cpu(cpu) {
q = per_cpu_ptr(p->q, cpu);
...
dev_ifb = alloc_netdev_mq(sizeof(struct ifb_private), "ifb%d",
ifb_setup, num_possible_cpus());
This is a very usual error.
You can have machines with 2 possibles cpus, numbered 0 and 8
Therere, you must use nr_cpu_ids here instead of num_possible_cpus()
^ permalink raw reply
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