* Re: SO_REUSEPORT - can it be done in kernel?
From: Thomas Graf @ 2011-03-01 12:18 UTC (permalink / raw)
To: Eric Dumazet
Cc: Herbert Xu, David Miller, rick.jones2, therbert, wsommerfeld,
daniel.baluta, netdev
In-Reply-To: <1298979909.3284.28.camel@edumazet-laptop>
On Tue, Mar 01, 2011 at 12:45:09PM +0100, Eric Dumazet wrote:
> ethtool -S eth0 | grep rx_pk
> rxq0: rx_pkts: ??
> rxq1: rx_pkts: ??
> rxq2: rx_pkts: ??
> rxq3: rx_pkts: ??
> rxq4: rx_pkts: ??
It could do multiqueue but it doesnt:
[root@hp-bl460cg7-01 ~]# ethtool -S eth0 | grep rx_pk
rxq0: rx_pkts: 1512
rxq1: rx_pkts: 462
rxq2: rx_pkts: 122
rxq3: rx_pkts: 24751393
rxq4: rx_pkts: 35
So, adding a third client making sure it would hit another queue:
rxq0: rx_pkts: 3041
rxq1: rx_pkts: 867
rxq2: rx_pkts: 4610476
rxq3: rx_pkts: 57418776
rxq4: rx_pkts: 40
... makes it use CPU 5 for rxq2 and the qps goes up from 250kqps to 270kqps
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
PerfTop: 18417 irqs/sec kernel:50.2% exact: 0.0% [1000Hz cpu-clock-msecs], (all, CPU: 5)
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
samples pcnt function DSO
_______ _____ _____________________________ ___________________________________________________________
12712.00 18.5% _raw_spin_unlock_irqrestore [kernel.kallsyms]
3697.00 5.4% isc_rwlock_lock /usr/lib64/libisc.so.62.0.1
1948.00 2.8% dns_rbt_findnode /usr/lib64/libdns.so.69.0.1
1809.00 2.6% isc_rwlock_unlock /usr/lib64/libisc.so.62.0.1
1631.00 2.4% __do_softirq [kernel.kallsyms]
1237.00 1.8% isc_stats_increment /usr/lib64/libisc.so.62.0.1
1106.00 1.6% clflush_cache_range [kernel.kallsyms]
964.00 1.4% _raw_spin_lock [kernel.kallsyms]
714.00 1.0% be_poll_rx /lib/modules/2.6.38-rc5+/kernel/drivers/net/benet/be2net.ko
630.00 0.9% __pthread_mutex_lock_internal /lib64/libpthread-2.12.so
627.00 0.9% dns_name_fullcompare /usr/lib64/libdns.so.69.0.1
582.00 0.8% dns_rbtnodechain_init /usr/lib64/libdns.so.69.0.1
552.00 0.8% sk_run_filter [kernel.kallsyms]
527.00 0.8% dns_name_getlabelsequence /usr/lib64/libdns.so.69.0.1
525.00 0.8% __pthread_mutex_unlock /lib64/libpthread-2.12.so
492.00 0.7% dns_name_equal /usr/lib64/libdns.so.69.0.1
468.00 0.7% isc___mempool_get /usr/lib64/libisc.so.62.0.1
462.00 0.7% __udp4_lib_lookup [kernel.kallsyms]
457.00 0.7% dns_acl_match /usr/lib64/libdns.so.69.0.1
453.00 0.7% dns_zone_attach /usr/lib64/libdns.so.69.0.1
451.00 0.7% fget_light [kernel.kallsyms]
443.00 0.6% dns_message_rendersection /usr/lib64/libdns.so.69.0.1
431.00 0.6% ipt_do_table [kernel.kallsyms]
429.00 0.6% nf_iterate [kernel.kallsyms]
422.00 0.6% __kmalloc_node_track_caller [kernel.kallsyms]
408.00 0.6% __domain_mapping [kernel.kallsyms]
387.00 0.6% dns_name_hash /usr/lib64/libdns.so.69.0.1
353.00 0.5% copy_user_generic_string [kernel.kallsyms]
349.00 0.5% dns_name_fromwire /usr/lib64/libdns.so.69.0.1
^ permalink raw reply
* Re: SO_REUSEPORT - can it be done in kernel?
From: Herbert Xu @ 2011-03-01 12:19 UTC (permalink / raw)
To: Eric Dumazet, David Miller, rick.jones2, therbert, wsommerfeld,
daniel.baluta, netdev
In-Reply-To: <20110301121829.GM9763@canuck.infradead.org>
On Tue, Mar 01, 2011 at 07:18:29AM -0500, Thomas Graf wrote:
>
>
> ... makes it use CPU 5 for rxq2 and the qps goes up from 250kqps to 270kqps
I think the increase here comes from the larger number of packets
in flight more than anything.
The bottleneck is still the TX queue (both software and hardware).
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [GIT/PATCH v3] xen network backend driver
From: Ben Hutchings @ 2011-03-01 12:28 UTC (permalink / raw)
To: Ian Campbell
Cc: netdev@vger.kernel.org, xen-devel, Jeremy Fitzhardinge,
Herbert Xu, Konrad Rzeszutek Wilk, Francois Romieu
In-Reply-To: <1298974009.5034.2029.camel@zakaz.uk.xensource.com>
On Tue, 2011-03-01 at 10:06 +0000, Ian Campbell wrote:
> On Mon, 2011-02-28 at 18:53 +0000, Ben Hutchings wrote:
> > On Mon, 2011-02-28 at 17:27 +0000, Ian Campbell wrote:
>
> > This should be defined as unsigned long (ideally it would be u64, but
> > that can't be updated atomically on 32-bit systems).
> [...]
> > Don't update last_rx; it's only needed on slave devices of a bond, and
> > the bonding driver takes care of it now.
>
> I made these two changes.
>
> > [...]
> > > +static int xenvif_change_mtu(struct net_device *dev, int mtu)
> > > +{
> > > + struct xenvif *vif = netdev_priv(dev);
> > > + int max = vif->can_sg ? 65535 - ETH_HLEN : ETH_DATA_LEN;
> > > + if (mtu > max)
> > > + return -EINVAL;
> > > + dev->mtu = mtu;
> > > + return 0;
> > > +}
> > [...]
> >
> > Since any VLAN tag must be inserted inline, shouldn't the MTU limit be
> > 65535 - VLAN_ETH_HLEN?
>
> In that case shouldn't the other case also be ETH_FRAME_LEN -
> VLAN_ETH_HLEN?
[...]
IEEE 802.3, in its infinite wisdom, says that the maximum frame length
is 1514, except that when an 802.1q tag is present it is 1518. So the
MTU for standard Ethernet remains 1500, regardless of the use of VLANs.
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* Re: SO_REUSEPORT - can it be done in kernel?
From: Herbert Xu @ 2011-03-01 12:32 UTC (permalink / raw)
To: Eric Dumazet
Cc: Thomas Graf, David Miller, rick.jones2, therbert, wsommerfeld,
daniel.baluta, netdev
In-Reply-To: <20110301115305.GA6984@gondor.apana.org.au>
On Tue, Mar 01, 2011 at 07:53:05PM +0800, Herbert Xu wrote:
> On Tue, Mar 01, 2011 at 12:45:09PM +0100, Eric Dumazet wrote:
> >
> > CPU 11 handles all TX completions : Its a potential bottleneck.
> >
> > I might ressurect XPS patch ;)
>
> Actually this has been my gripe all along with our TX multiqueue
> support. We should not decide the queue based on the socket, but
> on the current CPU.
>
> We already do the right thing for forwarded packets because there
> is no socket to latch onto, we just need to fix it for locally
> generated traffic.
>
> The odd packet reordering each time your scheduler decides to
> migrate the process isn't a big deal IMHO. If your scheduler
> is constantly moving things you've got bigger problems to worry
> about.
If anybody wants to play here is a patch to do exactly that:
net: Determine TX queue purely by current CPU
Distributing packets generated on one CPU to multiple queues
makes no sense. Nor does putting packets from multiple CPUs
into a single queue.
While this may introduce packet reordering should the scheduler
decide to migrate a thread, it isn't a big deal because migration
is meant to be a rare event, and nothing will die as long as the
ordering doesn't occur all the time.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
diff --git a/net/core/dev.c b/net/core/dev.c
index 8ae6631..87bd20a 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2164,22 +2164,12 @@ static u32 hashrnd __read_mostly;
u16 __skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb,
unsigned int num_tx_queues)
{
- u32 hash;
+ u32 hash = raw_smp_processor_id();
- if (skb_rx_queue_recorded(skb)) {
- hash = skb_get_rx_queue(skb);
- while (unlikely(hash >= num_tx_queues))
- hash -= num_tx_queues;
- return hash;
- }
+ while (unlikely(hash >= num_tx_queues))
+ hash -= num_tx_queues;
- if (skb->sk && skb->sk->sk_hash)
- hash = skb->sk->sk_hash;
- else
- hash = (__force u16) skb->protocol ^ skb->rxhash;
- hash = jhash_1word(hash, hashrnd);
-
- return (u16) (((u64) hash * num_tx_queues) >> 32);
+ return hash;
}
EXPORT_SYMBOL(__skb_tx_hash);
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply related
* Re: SO_REUSEPORT - can it be done in kernel?
From: Herbert Xu @ 2011-03-01 12:35 UTC (permalink / raw)
To: David Miller, rick.jones2, therbert, wsommerfeld, daniel.baluta,
netdev
In-Reply-To: <20110228113659.GA20726@gondor.apana.org.au>
On Mon, Feb 28, 2011 at 07:36:59PM +0800, Herbert Xu wrote:
> Here are the patches I used. Please don't them yet as I intend
> to clean them up quite a bit.
OK here is the version ready for merging (please retest them
though as I have changed things substantially).
The main change is that the legacy UDP code path is now gone
so we use the same UDP header generation whether corking is on
or off.
I will add IPv6 support in a later patch set.
Thanks!
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* [PATCH 5/5] udp: Add lockless transmit path
From: Herbert Xu @ 2011-03-01 12:36 UTC (permalink / raw)
To: David Miller, rick.jones2, therbert, wsommerfeld, daniel.baluta,
netdev, Thomas Graf
In-Reply-To: <20110301123519.GA7453@gondor.apana.org.au>
udp: Add lockless transmit path
The UDP transmit path has been running under the socket lock
for a long time because of the corking feature. This means that
transmitting to the same socket in multiple threads does not
scale at all.
However, as most users don't actually use corking, the locking
can be removed in the common case.
This patch creates a lockless fast path where corking is not used.
Please note that this does create a slight inaccuracy in the
enforcement of socket send buffer limits. In particular, we
may exceed the socket limit by up to (number of CPUs) * (packet
size) because of the way the limit is computed.
As the primary purpose of socket buffers is to indicate congestion,
this should not be a great problem for now.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---
net/ipv4/udp.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 9a6d326..bb9f707 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -802,6 +802,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
int err, is_udplite = IS_UDPLITE(sk);
int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
+ struct sk_buff *skb;
if (len > 0xFFFF)
return -EMSGSIZE;
@@ -816,6 +817,8 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
ipc.opt = NULL;
ipc.tx_flags = 0;
+ getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag;
+
if (up->pending) {
/*
* There are pending frames.
@@ -940,6 +943,17 @@ back_from_confirm:
if (!ipc.addr)
daddr = ipc.addr = rt->rt_dst;
+ /* Lockless fast path for the non-corking case. */
+ if (!corkreq) {
+ skb = ip_make_skb(sk, getfrag, msg->msg_iov, ulen,
+ sizeof(struct udphdr), &ipc, &rt,
+ msg->msg_flags);
+ err = PTR_ERR(skb);
+ if (skb && !IS_ERR(skb))
+ err = udp_send_skb(skb, daddr, dport);
+ goto out;
+ }
+
lock_sock(sk);
if (unlikely(up->pending)) {
/* The socket is already corked while preparing it. */
@@ -961,7 +975,6 @@ back_from_confirm:
do_append_data:
up->len += ulen;
- getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag;
err = ip_append_data(sk, getfrag, msg->msg_iov, ulen,
sizeof(struct udphdr), &ipc, &rt,
corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
^ permalink raw reply related
* [PATCH 4/5] udp: Switch to ip_finish_skb
From: Herbert Xu @ 2011-03-01 12:36 UTC (permalink / raw)
To: David Miller, rick.jones2, therbert, wsommerfeld, daniel.baluta,
netdev, Thomas Graf
In-Reply-To: <20110301123519.GA7453@gondor.apana.org.au>
udp: Switch to ip_finish_skb
This patch converts UDP to use the new ip_finish_skb API. This
would then allows us to more easily use ip_make_skb which allows
UDP to run without a socket lock.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---
include/net/udp.h | 11 ++++++
include/net/udplite.h | 12 +++++++
net/ipv4/udp.c | 83 ++++++++++++++++++++++++++++++--------------------
3 files changed, 73 insertions(+), 33 deletions(-)
diff --git a/include/net/udp.h b/include/net/udp.h
index bb967dd..b8563ba 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -144,6 +144,17 @@ static inline __wsum udp_csum_outgoing(struct sock *sk, struct sk_buff *skb)
return csum;
}
+static inline __wsum udp_csum(struct sk_buff *skb)
+{
+ __wsum csum = csum_partial(skb_transport_header(skb),
+ sizeof(struct udphdr), skb->csum);
+
+ for (skb = skb_shinfo(skb)->frag_list; skb; skb = skb->next) {
+ csum = csum_add(csum, skb->csum);
+ }
+ return csum;
+}
+
/* hash routines shared between UDPv4/6 and UDP-Litev4/6 */
static inline void udp_lib_hash(struct sock *sk)
{
diff --git a/include/net/udplite.h b/include/net/udplite.h
index afdffe6..673a024 100644
--- a/include/net/udplite.h
+++ b/include/net/udplite.h
@@ -115,6 +115,18 @@ static inline __wsum udplite_csum_outgoing(struct sock *sk, struct sk_buff *skb)
return csum;
}
+static inline __wsum udplite_csum(struct sk_buff *skb)
+{
+ struct sock *sk = skb->sk;
+ int cscov = udplite_sender_cscov(udp_sk(sk), udp_hdr(skb));
+ const int off = skb_transport_offset(skb);
+ const int len = skb->len - off;
+
+ skb->ip_summed = CHECKSUM_NONE; /* no HW support for checksumming */
+
+ return skb_checksum(skb, off, min(cscov, len), 0);
+}
+
extern void udplite4_register(void);
extern int udplite_get_port(struct sock *sk, unsigned short snum,
int (*scmp)(const struct sock *, const struct sock *));
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 8157b17..9a6d326 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -663,75 +663,72 @@ void udp_flush_pending_frames(struct sock *sk)
EXPORT_SYMBOL(udp_flush_pending_frames);
/**
- * udp4_hwcsum_outgoing - handle outgoing HW checksumming
- * @sk: socket we are sending on
+ * udp4_hwcsum - handle outgoing HW checksumming
* @skb: sk_buff containing the filled-in UDP header
* (checksum field must be zeroed out)
+ * @src: source IP address
+ * @dst: destination IP address
*/
-static void udp4_hwcsum_outgoing(struct sock *sk, struct sk_buff *skb,
- __be32 src, __be32 dst, int len)
+static void udp4_hwcsum(struct sk_buff *skb, __be32 src, __be32 dst)
{
- unsigned int offset;
struct udphdr *uh = udp_hdr(skb);
+ struct sk_buff *frags = skb_shinfo(skb)->frag_list;
+ int offset = skb_transport_offset(skb);
+ int len = skb->len - offset;
+ int hlen = len;
__wsum csum = 0;
- if (skb_queue_len(&sk->sk_write_queue) == 1) {
+ if (!frags) {
/*
* Only one fragment on the socket.
*/
skb->csum_start = skb_transport_header(skb) - skb->head;
skb->csum_offset = offsetof(struct udphdr, check);
- uh->check = ~csum_tcpudp_magic(src, dst, len, IPPROTO_UDP, 0);
+ uh->check = ~csum_tcpudp_magic(src, dst, len,
+ IPPROTO_UDP, 0);
} else {
/*
* HW-checksum won't work as there are two or more
* fragments on the socket so that all csums of sk_buffs
* should be together
*/
- offset = skb_transport_offset(skb);
- skb->csum = skb_checksum(skb, offset, skb->len - offset, 0);
+ do {
+ csum = csum_add(csum, frags->csum);
+ hlen -= frags->len;
+ } while ((frags = frags->next));
+ csum = skb_checksum(skb, offset, hlen, csum);
skb->ip_summed = CHECKSUM_NONE;
- skb_queue_walk(&sk->sk_write_queue, skb) {
- csum = csum_add(csum, skb->csum);
- }
-
uh->check = csum_tcpudp_magic(src, dst, len, IPPROTO_UDP, csum);
if (uh->check == 0)
uh->check = CSUM_MANGLED_0;
}
}
-/*
- * Push out all pending data as one UDP datagram. Socket is locked.
- */
-static int udp_push_pending_frames(struct sock *sk)
+static int udp_send_skb(struct sk_buff *skb, __be32 daddr, __be32 dport)
{
- struct udp_sock *up = udp_sk(sk);
+ struct sock *sk = skb->sk;
struct inet_sock *inet = inet_sk(sk);
- struct flowi *fl = &inet->cork.fl;
- struct sk_buff *skb;
struct udphdr *uh;
+ struct rtable *rt = (struct rtable *)skb_dst(skb);
int err = 0;
int is_udplite = IS_UDPLITE(sk);
+ int offset = skb_transport_offset(skb);
+ int len = skb->len - offset;
__wsum csum = 0;
- /* Grab the skbuff where UDP header space exists. */
- if ((skb = skb_peek(&sk->sk_write_queue)) == NULL)
- goto out;
-
/*
* Create a UDP header
*/
uh = udp_hdr(skb);
- uh->source = fl->fl_ip_sport;
- uh->dest = fl->fl_ip_dport;
- uh->len = htons(up->len);
+ uh->source = inet->inet_sport;
+ uh->dest = dport;
+ uh->len = htons(len);
uh->check = 0;
if (is_udplite) /* UDP-Lite */
- csum = udplite_csum_outgoing(sk, skb);
+ csum = udplite_csum(skb);
else if (sk->sk_no_check == UDP_CSUM_NOXMIT) { /* UDP csum disabled */
@@ -740,20 +737,20 @@ static int udp_push_pending_frames(struct sock *sk)
} else if (skb->ip_summed == CHECKSUM_PARTIAL) { /* UDP hardware csum */
- udp4_hwcsum_outgoing(sk, skb, fl->fl4_src, fl->fl4_dst, up->len);
+ udp4_hwcsum(skb, rt->rt_src, daddr);
goto send;
- } else /* `normal' UDP */
- csum = udp_csum_outgoing(sk, skb);
+ } else
+ csum = udp_csum(skb);
/* add protocol-dependent pseudo-header */
- uh->check = csum_tcpudp_magic(fl->fl4_src, fl->fl4_dst, up->len,
+ uh->check = csum_tcpudp_magic(rt->rt_src, daddr, len,
sk->sk_protocol, csum);
if (uh->check == 0)
uh->check = CSUM_MANGLED_0;
send:
- err = ip_push_pending_frames(sk);
+ err = ip_send_skb(skb);
if (err) {
if (err == -ENOBUFS && !inet->recverr) {
UDP_INC_STATS_USER(sock_net(sk),
@@ -763,6 +760,26 @@ send:
} else
UDP_INC_STATS_USER(sock_net(sk),
UDP_MIB_OUTDATAGRAMS, is_udplite);
+ return err;
+}
+
+/*
+ * Push out all pending data as one UDP datagram. Socket is locked.
+ */
+static int udp_push_pending_frames(struct sock *sk)
+{
+ struct udp_sock *up = udp_sk(sk);
+ struct inet_sock *inet = inet_sk(sk);
+ struct flowi *fl = &inet->cork.fl;
+ struct sk_buff *skb;
+ int err = 0;
+
+ skb = ip_finish_skb(sk);
+ if (!skb)
+ goto out;
+
+ err = udp_send_skb(skb, fl->fl4_dst, fl->fl_ip_dport);
+
out:
up->len = 0;
up->pending = 0;
^ permalink raw reply related
* [PATCH 1/5] inet: Remove unused sk_sndmsg_* from UFO
From: Herbert Xu @ 2011-03-01 12:36 UTC (permalink / raw)
To: David Miller, rick.jones2, therbert, wsommerfeld, daniel.baluta,
netdev, Thomas Graf
In-Reply-To: <20110301123519.GA7453@gondor.apana.org.au>
inet: Remove unused sk_sndmsg_* from UFO
UFO doesn't really use the sk_sndmsg_* parameters so touching
them is pointless. It can't use them anyway since the whole
point of UFO is to use the original pages without copying.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---
net/core/skbuff.c | 3 ---
net/ipv4/ip_output.c | 1 -
net/ipv6/ip6_output.c | 1 -
3 files changed, 5 deletions(-)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index d883dcc..97011a7 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2434,8 +2434,6 @@ int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,
return -ENOMEM;
/* initialize the next frag */
- sk->sk_sndmsg_page = page;
- sk->sk_sndmsg_off = 0;
skb_fill_page_desc(skb, frg_cnt, page, 0, 0);
skb->truesize += PAGE_SIZE;
atomic_add(PAGE_SIZE, &sk->sk_wmem_alloc);
@@ -2455,7 +2453,6 @@ int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,
return -EFAULT;
/* copy was successful so update the size parameters */
- sk->sk_sndmsg_off += copy;
frag->size += copy;
skb->len += copy;
skb->data_len += copy;
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 04c7b3b..d3a4540 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -767,7 +767,6 @@ static inline int ip_ufo_append_data(struct sock *sk,
skb->ip_summed = CHECKSUM_PARTIAL;
skb->csum = 0;
- sk->sk_sndmsg_off = 0;
/* specify the length of each IP datagram fragment */
skb_shinfo(skb)->gso_size = mtu - fragheaderlen;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 5f8d242..9965182 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1061,7 +1061,6 @@ static inline int ip6_ufo_append_data(struct sock *sk,
skb->ip_summed = CHECKSUM_PARTIAL;
skb->csum = 0;
- sk->sk_sndmsg_off = 0;
}
err = skb_append_datato_frags(sk,skb, getfrag, from,
^ permalink raw reply related
* [PATCH 3/5] inet: Add ip_make_skb and ip_finish_skb
From: Herbert Xu @ 2011-03-01 12:36 UTC (permalink / raw)
To: David Miller, rick.jones2, therbert, wsommerfeld, daniel.baluta,
netdev, Thomas Graf
In-Reply-To: <20110301123519.GA7453@gondor.apana.org.au>
inet: Add ip_make_skb and ip_finish_skb
This patch adds the helper ip_make_skb which is like ip_append_data
and ip_push_pending_frames all rolled into one, except that it does
not send the skb produced. The sending part is carried out by
ip_send_skb, which the transport protocol can call after it has
tweaked the skb.
It is meant to be called in cases where corking is not used should
have a one-to-one correspondence to sendmsg.
This patch also adds the helper ip_finish_skb which is meant to
be replace ip_push_pending_frames when corking is required.
Previously the protocol stack would peek at the socket write
queue and add its header to the first packet. With ip_finish_skb,
the protocol stack can directly operate on the final skb instead,
just like the non-corking case with ip_make_skb.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---
include/net/ip.h | 16 ++++++++++++
net/ipv4/ip_output.c | 65 ++++++++++++++++++++++++++++++++++++++++-----------
2 files changed, 67 insertions(+), 14 deletions(-)
diff --git a/include/net/ip.h b/include/net/ip.h
index 67fac78..a4f6311 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -116,8 +116,24 @@ extern int ip_append_data(struct sock *sk,
extern int ip_generic_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb);
extern ssize_t ip_append_page(struct sock *sk, struct page *page,
int offset, size_t size, int flags);
+extern struct sk_buff *__ip_make_skb(struct sock *sk,
+ struct sk_buff_head *queue,
+ struct inet_cork *cork);
+extern int ip_send_skb(struct sk_buff *skb);
extern int ip_push_pending_frames(struct sock *sk);
extern void ip_flush_pending_frames(struct sock *sk);
+extern struct sk_buff *ip_make_skb(struct sock *sk,
+ int getfrag(void *from, char *to, int offset, int len,
+ int odd, struct sk_buff *skb),
+ void *from, int length, int transhdrlen,
+ struct ipcm_cookie *ipc,
+ struct rtable **rtp,
+ unsigned int flags);
+
+static inline struct sk_buff *ip_finish_skb(struct sock *sk)
+{
+ return __ip_make_skb(sk, &sk->sk_write_queue, &inet_sk(sk)->cork);
+}
/* datagram.c */
extern int ip4_datagram_connect(struct sock *sk,
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 1dd5ecc..460308c 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1267,9 +1267,9 @@ static void ip_cork_release(struct inet_cork *cork)
* Combined all pending IP fragments on the socket as one IP datagram
* and push them out.
*/
-static int __ip_push_pending_frames(struct sock *sk,
- struct sk_buff_head *queue,
- struct inet_cork *cork)
+struct sk_buff *__ip_make_skb(struct sock *sk,
+ struct sk_buff_head *queue,
+ struct inet_cork *cork)
{
struct sk_buff *skb, *tmp_skb;
struct sk_buff **tail_skb;
@@ -1280,7 +1280,6 @@ static int __ip_push_pending_frames(struct sock *sk,
struct iphdr *iph;
__be16 df = 0;
__u8 ttl;
- int err = 0;
if ((skb = __skb_dequeue(queue)) == NULL)
goto out;
@@ -1351,28 +1350,37 @@ static int __ip_push_pending_frames(struct sock *sk,
icmp_out_count(net, ((struct icmphdr *)
skb_transport_header(skb))->type);
- /* Netfilter gets whole the not fragmented skb. */
+ ip_cork_release(cork);
+out:
+ return skb;
+}
+
+int ip_send_skb(struct sk_buff *skb)
+{
+ struct net *net = sock_net(skb->sk);
+ int err;
+
err = ip_local_out(skb);
if (err) {
if (err > 0)
err = net_xmit_errno(err);
if (err)
- goto error;
+ IP_INC_STATS(net, IPSTATS_MIB_OUTDISCARDS);
}
-out:
- ip_cork_release(cork);
return err;
-
-error:
- IP_INC_STATS(net, IPSTATS_MIB_OUTDISCARDS);
- goto out;
}
int ip_push_pending_frames(struct sock *sk)
{
- return __ip_push_pending_frames(sk, &sk->sk_write_queue,
- &inet_sk(sk)->cork);
+ struct sk_buff *skb;
+
+ skb = ip_finish_skb(sk);
+ if (!skb)
+ return 0;
+
+ /* Netfilter gets whole the not fragmented skb. */
+ return ip_send_skb(skb);
}
/*
@@ -1395,6 +1403,35 @@ void ip_flush_pending_frames(struct sock *sk)
__ip_flush_pending_frames(sk, &sk->sk_write_queue, &inet_sk(sk)->cork);
}
+struct sk_buff *ip_make_skb(struct sock *sk,
+ int getfrag(void *from, char *to, int offset,
+ int len, int odd, struct sk_buff *skb),
+ void *from, int length, int transhdrlen,
+ struct ipcm_cookie *ipc, struct rtable **rtp,
+ unsigned int flags)
+{
+ struct inet_cork cork = {};
+ struct sk_buff_head queue;
+ int err;
+
+ if (flags & MSG_PROBE)
+ return NULL;
+
+ __skb_queue_head_init(&queue);
+
+ err = ip_setup_cork(sk, &cork, ipc, rtp);
+ if (err)
+ return ERR_PTR(err);
+
+ err = __ip_append_data(sk, &queue, &cork, getfrag,
+ from, length, transhdrlen, flags);
+ if (err) {
+ __ip_flush_pending_frames(sk, &queue, &cork);
+ return ERR_PTR(err);
+ }
+
+ return __ip_make_skb(sk, &queue, &cork);
+}
/*
* Fetch data from kernel space and fill in checksum if needed.
^ permalink raw reply related
* [PATCH 2/5] inet: Remove explicit write references to sk/inet in ip_append_data
From: Herbert Xu @ 2011-03-01 12:36 UTC (permalink / raw)
To: David Miller, rick.jones2, therbert, wsommerfeld, daniel.baluta,
netdev, Thomas Graf
In-Reply-To: <20110301123519.GA7453@gondor.apana.org.au>
inet: Remove explicit write references to sk/inet in ip_append_data
In order to allow simultaneous calls to ip_append_data on the same
socket, it must not modify any shared state in sk or inet (other
than those that are designed to allow that such as atomic counters).
This patch abstracts out write references to sk and inet_sk in
ip_append_data and its friends so that we may use the underlying
code in parallel.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---
include/net/inet_sock.h | 23 ++--
net/ipv4/ip_output.c | 238 ++++++++++++++++++++++++++++--------------------
2 files changed, 154 insertions(+), 107 deletions(-)
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
index 8181498..b3de102 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -86,6 +86,19 @@ static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk)
return (struct inet_request_sock *)sk;
}
+struct inet_cork {
+ unsigned int flags;
+ unsigned int fragsize;
+ struct ip_options *opt;
+ struct dst_entry *dst;
+ int length; /* Total length of all frames */
+ __be32 addr;
+ struct flowi fl;
+ struct page *page;
+ u32 off;
+ u8 tx_flags;
+};
+
struct ip_mc_socklist;
struct ipv6_pinfo;
struct rtable;
@@ -143,15 +156,7 @@ struct inet_sock {
int mc_index;
__be32 mc_addr;
struct ip_mc_socklist __rcu *mc_list;
- struct {
- unsigned int flags;
- unsigned int fragsize;
- struct ip_options *opt;
- struct dst_entry *dst;
- int length; /* Total length of all frames */
- __be32 addr;
- struct flowi fl;
- } cork;
+ struct inet_cork cork;
};
#define IPCORK_OPT 1 /* ip-options has been held in ipcork.opt */
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index d3a4540..1dd5ecc 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -733,6 +733,7 @@ csum_page(struct page *page, int offset, int copy)
}
static inline int ip_ufo_append_data(struct sock *sk,
+ struct sk_buff_head *queue,
int getfrag(void *from, char *to, int offset, int len,
int odd, struct sk_buff *skb),
void *from, int length, int hh_len, int fragheaderlen,
@@ -745,7 +746,7 @@ static inline int ip_ufo_append_data(struct sock *sk,
* device, so create one single skb packet containing complete
* udp datagram
*/
- if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) {
+ if ((skb = skb_peek_tail(queue)) == NULL) {
skb = sock_alloc_send_skb(sk,
hh_len + fragheaderlen + transhdrlen + 20,
(flags & MSG_DONTWAIT), &err);
@@ -771,35 +772,24 @@ static inline int ip_ufo_append_data(struct sock *sk,
/* specify the length of each IP datagram fragment */
skb_shinfo(skb)->gso_size = mtu - fragheaderlen;
skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
- __skb_queue_tail(&sk->sk_write_queue, skb);
+ __skb_queue_tail(queue, skb);
}
return skb_append_datato_frags(sk, skb, getfrag, from,
(length - transhdrlen));
}
-/*
- * ip_append_data() and ip_append_page() can make one large IP datagram
- * from many pieces of data. Each pieces will be holded on the socket
- * until ip_push_pending_frames() is called. Each piece can be a page
- * or non-page data.
- *
- * Not only UDP, other transport protocols - e.g. raw sockets - can use
- * this interface potentially.
- *
- * LATER: length must be adjusted by pad at tail, when it is required.
- */
-int ip_append_data(struct sock *sk,
- int getfrag(void *from, char *to, int offset, int len,
- int odd, struct sk_buff *skb),
- void *from, int length, int transhdrlen,
- struct ipcm_cookie *ipc, struct rtable **rtp,
- unsigned int flags)
+static int __ip_append_data(struct sock *sk, struct sk_buff_head *queue,
+ struct inet_cork *cork,
+ int getfrag(void *from, char *to, int offset,
+ int len, int odd, struct sk_buff *skb),
+ void *from, int length, int transhdrlen,
+ unsigned int flags)
{
struct inet_sock *inet = inet_sk(sk);
struct sk_buff *skb;
- struct ip_options *opt = NULL;
+ struct ip_options *opt = inet->cork.opt;
int hh_len;
int exthdrlen;
int mtu;
@@ -808,58 +798,19 @@ int ip_append_data(struct sock *sk,
int offset = 0;
unsigned int maxfraglen, fragheaderlen;
int csummode = CHECKSUM_NONE;
- struct rtable *rt;
-
- if (flags&MSG_PROBE)
- return 0;
+ struct rtable *rt = (struct rtable *)cork->dst;
- if (skb_queue_empty(&sk->sk_write_queue)) {
- /*
- * setup for corking.
- */
- opt = ipc->opt;
- if (opt) {
- if (inet->cork.opt == NULL) {
- inet->cork.opt = kmalloc(sizeof(struct ip_options) + 40, sk->sk_allocation);
- if (unlikely(inet->cork.opt == NULL))
- return -ENOBUFS;
- }
- memcpy(inet->cork.opt, opt, sizeof(struct ip_options)+opt->optlen);
- inet->cork.flags |= IPCORK_OPT;
- inet->cork.addr = ipc->addr;
- }
- rt = *rtp;
- if (unlikely(!rt))
- return -EFAULT;
- /*
- * We steal reference to this route, caller should not release it
- */
- *rtp = NULL;
- inet->cork.fragsize = mtu = inet->pmtudisc == IP_PMTUDISC_PROBE ?
- rt->dst.dev->mtu :
- dst_mtu(rt->dst.path);
- inet->cork.dst = &rt->dst;
- inet->cork.length = 0;
- sk->sk_sndmsg_page = NULL;
- sk->sk_sndmsg_off = 0;
- exthdrlen = rt->dst.header_len;
- length += exthdrlen;
- transhdrlen += exthdrlen;
- } else {
- rt = (struct rtable *)inet->cork.dst;
- if (inet->cork.flags & IPCORK_OPT)
- opt = inet->cork.opt;
+ exthdrlen = transhdrlen ? rt->dst.header_len : 0;
+ length += exthdrlen;
+ transhdrlen += exthdrlen;
+ mtu = inet->cork.fragsize;
- transhdrlen = 0;
- exthdrlen = 0;
- mtu = inet->cork.fragsize;
- }
hh_len = LL_RESERVED_SPACE(rt->dst.dev);
fragheaderlen = sizeof(struct iphdr) + (opt ? opt->optlen : 0);
maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen;
- if (inet->cork.length + length > 0xFFFF - fragheaderlen) {
+ if (cork->length + length > 0xFFFF - fragheaderlen) {
ip_local_error(sk, EMSGSIZE, rt->rt_dst, inet->inet_dport,
mtu-exthdrlen);
return -EMSGSIZE;
@@ -875,15 +826,15 @@ int ip_append_data(struct sock *sk,
!exthdrlen)
csummode = CHECKSUM_PARTIAL;
- skb = skb_peek_tail(&sk->sk_write_queue);
+ skb = skb_peek_tail(queue);
- inet->cork.length += length;
+ cork->length += length;
if (((length > mtu) || (skb && skb_is_gso(skb))) &&
(sk->sk_protocol == IPPROTO_UDP) &&
(rt->dst.dev->features & NETIF_F_UFO)) {
- err = ip_ufo_append_data(sk, getfrag, from, length, hh_len,
- fragheaderlen, transhdrlen, mtu,
- flags);
+ err = ip_ufo_append_data(sk, queue, getfrag, from, length,
+ hh_len, fragheaderlen, transhdrlen,
+ mtu, flags);
if (err)
goto error;
return 0;
@@ -960,7 +911,7 @@ alloc_new_skb:
else
/* only the initial fragment is
time stamped */
- ipc->tx_flags = 0;
+ cork->tx_flags = 0;
}
if (skb == NULL)
goto error;
@@ -971,7 +922,7 @@ alloc_new_skb:
skb->ip_summed = csummode;
skb->csum = 0;
skb_reserve(skb, hh_len);
- skb_shinfo(skb)->tx_flags = ipc->tx_flags;
+ skb_shinfo(skb)->tx_flags = cork->tx_flags;
/*
* Find where to start putting bytes.
@@ -1008,7 +959,7 @@ alloc_new_skb:
/*
* Put the packet on the pending queue.
*/
- __skb_queue_tail(&sk->sk_write_queue, skb);
+ __skb_queue_tail(queue, skb);
continue;
}
@@ -1028,8 +979,8 @@ alloc_new_skb:
} else {
int i = skb_shinfo(skb)->nr_frags;
skb_frag_t *frag = &skb_shinfo(skb)->frags[i-1];
- struct page *page = sk->sk_sndmsg_page;
- int off = sk->sk_sndmsg_off;
+ struct page *page = cork->page;
+ int off = cork->off;
unsigned int left;
if (page && (left = PAGE_SIZE - off) > 0) {
@@ -1041,7 +992,7 @@ alloc_new_skb:
goto error;
}
get_page(page);
- skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0);
+ skb_fill_page_desc(skb, i, page, off, 0);
frag = &skb_shinfo(skb)->frags[i];
}
} else if (i < MAX_SKB_FRAGS) {
@@ -1052,8 +1003,8 @@ alloc_new_skb:
err = -ENOMEM;
goto error;
}
- sk->sk_sndmsg_page = page;
- sk->sk_sndmsg_off = 0;
+ cork->page = page;
+ cork->off = 0;
skb_fill_page_desc(skb, i, page, 0, 0);
frag = &skb_shinfo(skb)->frags[i];
@@ -1065,7 +1016,7 @@ alloc_new_skb:
err = -EFAULT;
goto error;
}
- sk->sk_sndmsg_off += copy;
+ cork->off += copy;
frag->size += copy;
skb->len += copy;
skb->data_len += copy;
@@ -1079,11 +1030,87 @@ alloc_new_skb:
return 0;
error:
- inet->cork.length -= length;
+ cork->length -= length;
IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTDISCARDS);
return err;
}
+static int ip_setup_cork(struct sock *sk, struct inet_cork *cork,
+ struct ipcm_cookie *ipc, struct rtable **rtp)
+{
+ struct inet_sock *inet = inet_sk(sk);
+ struct ip_options *opt;
+ struct rtable *rt;
+
+ /*
+ * setup for corking.
+ */
+ opt = ipc->opt;
+ if (opt) {
+ if (cork->opt == NULL) {
+ cork->opt = kmalloc(sizeof(struct ip_options) + 40,
+ sk->sk_allocation);
+ if (unlikely(cork->opt == NULL))
+ return -ENOBUFS;
+ }
+ memcpy(cork->opt, opt, sizeof(struct ip_options) + opt->optlen);
+ cork->flags |= IPCORK_OPT;
+ cork->addr = ipc->addr;
+ }
+ rt = *rtp;
+ if (unlikely(!rt))
+ return -EFAULT;
+ /*
+ * We steal reference to this route, caller should not release it
+ */
+ *rtp = NULL;
+ cork->fragsize = inet->pmtudisc == IP_PMTUDISC_PROBE ?
+ rt->dst.dev->mtu : dst_mtu(rt->dst.path);
+ cork->dst = &rt->dst;
+ cork->length = 0;
+ cork->tx_flags = ipc->tx_flags;
+ cork->page = NULL;
+ cork->off = 0;
+
+ return 0;
+}
+
+/*
+ * ip_append_data() and ip_append_page() can make one large IP datagram
+ * from many pieces of data. Each pieces will be holded on the socket
+ * until ip_push_pending_frames() is called. Each piece can be a page
+ * or non-page data.
+ *
+ * Not only UDP, other transport protocols - e.g. raw sockets - can use
+ * this interface potentially.
+ *
+ * LATER: length must be adjusted by pad at tail, when it is required.
+ */
+int ip_append_data(struct sock *sk,
+ int getfrag(void *from, char *to, int offset, int len,
+ int odd, struct sk_buff *skb),
+ void *from, int length, int transhdrlen,
+ struct ipcm_cookie *ipc, struct rtable **rtp,
+ unsigned int flags)
+{
+ struct inet_sock *inet = inet_sk(sk);
+ int err;
+
+ if (flags&MSG_PROBE)
+ return 0;
+
+ if (skb_queue_empty(&sk->sk_write_queue)) {
+ err = ip_setup_cork(sk, &inet->cork, ipc, rtp);
+ if (err)
+ return err;
+ } else {
+ transhdrlen = 0;
+ }
+
+ return __ip_append_data(sk, &sk->sk_write_queue, &inet->cork, getfrag,
+ from, length, transhdrlen, flags);
+}
+
ssize_t ip_append_page(struct sock *sk, struct page *page,
int offset, size_t size, int flags)
{
@@ -1227,40 +1254,42 @@ error:
return err;
}
-static void ip_cork_release(struct inet_sock *inet)
+static void ip_cork_release(struct inet_cork *cork)
{
- inet->cork.flags &= ~IPCORK_OPT;
- kfree(inet->cork.opt);
- inet->cork.opt = NULL;
- dst_release(inet->cork.dst);
- inet->cork.dst = NULL;
+ cork->flags &= ~IPCORK_OPT;
+ kfree(cork->opt);
+ cork->opt = NULL;
+ dst_release(cork->dst);
+ cork->dst = NULL;
}
/*
* Combined all pending IP fragments on the socket as one IP datagram
* and push them out.
*/
-int ip_push_pending_frames(struct sock *sk)
+static int __ip_push_pending_frames(struct sock *sk,
+ struct sk_buff_head *queue,
+ struct inet_cork *cork)
{
struct sk_buff *skb, *tmp_skb;
struct sk_buff **tail_skb;
struct inet_sock *inet = inet_sk(sk);
struct net *net = sock_net(sk);
struct ip_options *opt = NULL;
- struct rtable *rt = (struct rtable *)inet->cork.dst;
+ struct rtable *rt = (struct rtable *)cork->dst;
struct iphdr *iph;
__be16 df = 0;
__u8 ttl;
int err = 0;
- if ((skb = __skb_dequeue(&sk->sk_write_queue)) == NULL)
+ if ((skb = __skb_dequeue(queue)) == NULL)
goto out;
tail_skb = &(skb_shinfo(skb)->frag_list);
/* move skb->data to ip header from ext header */
if (skb->data < skb_network_header(skb))
__skb_pull(skb, skb_network_offset(skb));
- while ((tmp_skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) {
+ while ((tmp_skb = __skb_dequeue(queue)) != NULL) {
__skb_pull(tmp_skb, skb_network_header_len(skb));
*tail_skb = tmp_skb;
tail_skb = &(tmp_skb->next);
@@ -1286,8 +1315,8 @@ int ip_push_pending_frames(struct sock *sk)
ip_dont_fragment(sk, &rt->dst)))
df = htons(IP_DF);
- if (inet->cork.flags & IPCORK_OPT)
- opt = inet->cork.opt;
+ if (cork->flags & IPCORK_OPT)
+ opt = cork->opt;
if (rt->rt_type == RTN_MULTICAST)
ttl = inet->mc_ttl;
@@ -1299,7 +1328,7 @@ int ip_push_pending_frames(struct sock *sk)
iph->ihl = 5;
if (opt) {
iph->ihl += opt->optlen>>2;
- ip_options_build(skb, opt, inet->cork.addr, rt, 0);
+ ip_options_build(skb, opt, cork->addr, rt, 0);
}
iph->tos = inet->tos;
iph->frag_off = df;
@@ -1315,7 +1344,7 @@ int ip_push_pending_frames(struct sock *sk)
* Steal rt from cork.dst to avoid a pair of atomic_inc/atomic_dec
* on dst refcount
*/
- inet->cork.dst = NULL;
+ cork->dst = NULL;
skb_dst_set(skb, &rt->dst);
if (iph->protocol == IPPROTO_ICMP)
@@ -1332,7 +1361,7 @@ int ip_push_pending_frames(struct sock *sk)
}
out:
- ip_cork_release(inet);
+ ip_cork_release(cork);
return err;
error:
@@ -1340,17 +1369,30 @@ error:
goto out;
}
+int ip_push_pending_frames(struct sock *sk)
+{
+ return __ip_push_pending_frames(sk, &sk->sk_write_queue,
+ &inet_sk(sk)->cork);
+}
+
/*
* Throw away all pending data on the socket.
*/
-void ip_flush_pending_frames(struct sock *sk)
+static void __ip_flush_pending_frames(struct sock *sk,
+ struct sk_buff_head *queue,
+ struct inet_cork *cork)
{
struct sk_buff *skb;
- while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL)
+ while ((skb = __skb_dequeue_tail(queue)) != NULL)
kfree_skb(skb);
- ip_cork_release(inet_sk(sk));
+ ip_cork_release(cork);
+}
+
+void ip_flush_pending_frames(struct sock *sk)
+{
+ __ip_flush_pending_frames(sk, &sk->sk_write_queue, &inet_sk(sk)->cork);
}
^ permalink raw reply related
* Re: [PATCH 2/4] slub,rcu: don't assume the size of struct rcu_head
From: Pekka Enberg @ 2011-03-01 13:00 UTC (permalink / raw)
To: Lai Jiangshan
Cc: Ingo Molnar, Paul E. McKenney, Christoph Lameter, Eric Dumazet,
David S. Miller, Matt Mackall, linux-mm, linux-kernel, netdev
In-Reply-To: <4D6CA852.3060303@cn.fujitsu.com>
On Tue, Mar 1, 2011 at 10:03 AM, Lai Jiangshan <laijs@cn.fujitsu.com> wrote:
> The size of struct rcu_head may be changed. When it becomes larger,
> it will pollute the page array.
>
> We reserve some some bytes for struct rcu_head when a slab
> is allocated in this situation.
>
> Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
The SLAB and SLUB patches are fine by me if there are going to be real
users for this. Christoph, Paul?
--
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: SO_REUSEPORT - can it be done in kernel?
From: Eric Dumazet @ 2011-03-01 13:03 UTC (permalink / raw)
To: Herbert Xu
Cc: Thomas Graf, David Miller, rick.jones2, therbert, wsommerfeld,
daniel.baluta, netdev
In-Reply-To: <20110301115305.GA6984@gondor.apana.org.au>
Le mardi 01 mars 2011 à 19:53 +0800, Herbert Xu a écrit :
> On Tue, Mar 01, 2011 at 12:45:09PM +0100, Eric Dumazet wrote:
> >
> > CPU 11 handles all TX completions : Its a potential bottleneck.
> >
> > I might ressurect XPS patch ;)
>
> Actually this has been my gripe all along with our TX multiqueue
> support. We should not decide the queue based on the socket, but
> on the current CPU.
>
> We already do the right thing for forwarded packets because there
> is no socket to latch onto, we just need to fix it for locally
> generated traffic.
>
I believe its now done properly (in net-next-2.6) with commit
4f57c087de9b46182 (net: implement mechanism for HW based QOS)
> The odd packet reordering each time your scheduler decides to
> migrate the process isn't a big deal IMHO. If your scheduler
> is constantly moving things you've got bigger problems to worry
> about.
Well, BENET has one TX queue anyway...
^ permalink raw reply
* Re: SO_REUSEPORT - can it be done in kernel?
From: Eric Dumazet @ 2011-03-01 13:04 UTC (permalink / raw)
To: Herbert Xu
Cc: Thomas Graf, David Miller, rick.jones2, therbert, wsommerfeld,
daniel.baluta, netdev
In-Reply-To: <20110301123250.GA7368@gondor.apana.org.au>
Le mardi 01 mars 2011 à 20:32 +0800, Herbert Xu a écrit :
> On Tue, Mar 01, 2011 at 07:53:05PM +0800, Herbert Xu wrote:
> > On Tue, Mar 01, 2011 at 12:45:09PM +0100, Eric Dumazet wrote:
> > >
> > > CPU 11 handles all TX completions : Its a potential bottleneck.
> > >
> > > I might ressurect XPS patch ;)
> >
> > Actually this has been my gripe all along with our TX multiqueue
> > support. We should not decide the queue based on the socket, but
> > on the current CPU.
> >
> > We already do the right thing for forwarded packets because there
> > is no socket to latch onto, we just need to fix it for locally
> > generated traffic.
> >
> > The odd packet reordering each time your scheduler decides to
> > migrate the process isn't a big deal IMHO. If your scheduler
> > is constantly moving things you've got bigger problems to worry
> > about.
>
> If anybody wants to play here is a patch to do exactly that:
>
> net: Determine TX queue purely by current CPU
>
> Distributing packets generated on one CPU to multiple queues
> makes no sense. Nor does putting packets from multiple CPUs
> into a single queue.
>
> While this may introduce packet reordering should the scheduler
> decide to migrate a thread, it isn't a big deal because migration
> is meant to be a rare event, and nothing will die as long as the
> ordering doesn't occur all the time.
>
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
>
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 8ae6631..87bd20a 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -2164,22 +2164,12 @@ static u32 hashrnd __read_mostly;
> u16 __skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb,
> unsigned int num_tx_queues)
> {
> - u32 hash;
> + u32 hash = raw_smp_processor_id();
>
> - if (skb_rx_queue_recorded(skb)) {
> - hash = skb_get_rx_queue(skb);
> - while (unlikely(hash >= num_tx_queues))
> - hash -= num_tx_queues;
> - return hash;
> - }
> + while (unlikely(hash >= num_tx_queues))
> + hash -= num_tx_queues;
>
> - if (skb->sk && skb->sk->sk_hash)
> - hash = skb->sk->sk_hash;
> - else
> - hash = (__force u16) skb->protocol ^ skb->rxhash;
> - hash = jhash_1word(hash, hashrnd);
> -
> - return (u16) (((u64) hash * num_tx_queues) >> 32);
> + return hash;
> }
> EXPORT_SYMBOL(__skb_tx_hash);
>
> Cheers,
Well, some machines have 4096 cpus ;)
^ permalink raw reply
* Re: SO_REUSEPORT - can it be done in kernel?
From: Herbert Xu @ 2011-03-01 13:11 UTC (permalink / raw)
To: Eric Dumazet
Cc: Thomas Graf, David Miller, rick.jones2, therbert, wsommerfeld,
daniel.baluta, netdev
In-Reply-To: <1298984669.3284.99.camel@edumazet-laptop>
On Tue, Mar 01, 2011 at 02:04:29PM +0100, Eric Dumazet wrote:
> Well, some machines have 4096 cpus ;)
Well just change it to use the multiplication then :)
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: SO_REUSEPORT - can it be done in kernel?
From: Herbert Xu @ 2011-03-01 13:18 UTC (permalink / raw)
To: Eric Dumazet
Cc: Thomas Graf, David Miller, rick.jones2, therbert, wsommerfeld,
daniel.baluta, netdev
In-Reply-To: <1298984609.3284.98.camel@edumazet-laptop>
On Tue, Mar 01, 2011 at 02:03:29PM +0100, Eric Dumazet wrote:
>
> I believe its now done properly (in net-next-2.6) with commit
> 4f57c087de9b46182 (net: implement mechanism for HW based QOS)
Nope, that has nothing to do with this.
> > The odd packet reordering each time your scheduler decides to
> > migrate the process isn't a big deal IMHO. If your scheduler
> > is constantly moving things you've got bigger problems to worry
> > about.
>
> Well, BENET has one TX queue anyway...
Interesting. So I wonder which lock is showing up at the top
of the profile with a single socket then. As it's definitely
going away with multiple sockets, that means it's not the TX
queue lock.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: SO_REUSEPORT - can it be done in kernel?
From: Herbert Xu @ 2011-03-01 13:27 UTC (permalink / raw)
To: Eric Dumazet, David Miller, rick.jones2, therbert, wsommerfeld,
daniel.baluta, netdev
In-Reply-To: <20110301120112.GL9763@canuck.infradead.org>
On Tue, Mar 01, 2011 at 07:01:12AM -0500, Thomas Graf wrote:
> On Tue, Mar 01, 2011 at 12:45:09PM +0100, Eric Dumazet wrote:
>
> This is how perf top looks like with SO_REUSEPORT
>
> ----------------------------------------------------------------------------------------------------------------------------------
> PerfTop: 27498 irqs/sec kernel:50.5% exact: 0.0% [1000Hz cpu-clock-msecs], (all, CPU: 1)
> ----------------------------------------------------------------------------------------------------------------------------------
>
> samples pcnt function DSO
> _______ _____ _____________________________ __________________
>
> 16464.00 6.0% isc_rwlock_lock libisc.so.62.0.1
> 15462.00 5.7% intel_idle [kernel.kallsyms]
So was this a RHEL6 kernel? I wonder if that is what's making it
perform better.
I guess we'll find out tomorrow.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [Lxc-users] Bad checksums and lost packets with macvlan on dummy
From: Daniel Lezcano @ 2011-03-01 13:29 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Andrian Nord, lxc-users, Patrick McHardy, Linux Netdev List
In-Reply-To: <1298879114.8726.131.camel@edumazet-laptop>
On 02/28/2011 08:45 AM, Eric Dumazet wrote:
> Le dimanche 27 février 2011 à 21:35 +0100, Daniel Lezcano a écrit :
>> On 02/27/2011 08:50 PM, Eric Dumazet wrote:
>>> Le dimanche 27 février 2011 à 16:14 +0100, Daniel Lezcano a écrit :
>>>> On 02/23/2011 06:13 PM, Andrian Nord wrote:
>>>>> On Mon, Feb 21, 2011 at 05:07:31PM +0100, Daniel Lezcano wrote:
>>>>>> I Cc'ed the netdev mailing list and Patrick in case my analysis is wrong
>>>>>> or incomplete.
>>>>> I'm confirming, that this happens only when macvlan's are onto dummy net
>>>>> device. In case of some physical interface under macvlan there is no lost
>>>>> packages and no broken checksums.
>>>> I did some tests with a 2.6.35 kernel version and it seems the checksum
>>>> errors do not appear.
>>>> I noticed there are some changes in the dummy setup function:
>>>>
>>>> dev->features |= NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO;
>>>> dev->features |= NETIF_F_NO_CSUM | NETIF_F_HIGHDMA | NETIF_F_LLTX;
>>>>
>>>>
>>>> May be that was introduced by commit:
>>>>
>>>> commit 6d81f41c58c69ddde497e9e640ba5805aa26e78c
>>>> Author: Eric Dumazet<eric.dumazet@gmail.com>
>>>> Date: Mon Sep 27 20:50:33 2010 +0000
>>>>
>>>> dummy: percpu stats and lockless xmit
>>>>
>>>> Converts dummy network device driver to :
>>>>
>>>> - percpu stats
>>>>
>>>> - 64bit stats
>>>>
>>>> - lockless xmit (NETIF_F_LLTX)
>>>>
>>>> - performance features added (NETIF_F_SG | NETIF_F_FRAGLIST |
>>>> NETIF_F_TSO | NETIF_F_NO_CSUM | NETIF_F_HIGHDMA)
>>>>
>>>> Signed-off-by: Eric Dumazet<eric.dumazet@gmail.com>
>>>> Signed-off-by: David S. Miller<davem@davemloft.net>
>>>>
>>>>
>>>> Eric,
>>>>
>>>> Andrian is observing, with a couple of macvlan (in bridge mode) on top
>>>> of a dummy interface, a lot of checksums error and packets drop.
>>>> Each macvlan is in a different network namespace and the dummy interface
>>>> is in the init_net.
>>>>
>>>> Any ideas ?
>>> Not sure I understand... I thought dummy was dropping all frames
>>> anyway ?
>>>
>>> static netdev_tx_t dummy_xmit(struct sk_buff *skb, struct net_device *dev)
>>> {
>>> struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats);
>>>
>>> u64_stats_update_begin(&dstats->syncp);
>>> dstats->tx_packets++;
>>> dstats->tx_bytes += skb->len;
>>> u64_stats_update_end(&dstats->syncp);
>>>
>>> dev_kfree_skb(skb);
>>> return NETDEV_TX_OK;
>>> }
>>>
>>>
>>> Maybe you could describe the setup ?
>> Yes, it is very simple.
>>
>> There are two network namespaces.
>>
>> macvlan1 is in network namespace 1
>> macvlan2 is in network namespace 2
>>
>> Both are in "bridge" mode, so they can communicate together.
>> The lower device is dummy0 in the init network namespace.
>>
>> IMO the problem is coming from the macvlan driver:
>>
>> dev->features = lowerdev->features& MACVLAN_FEATURES
>>
>> As dummy0 has the offloading capabilities set on, the macvlan driver
>> inherit these features.
>>
>> In the normal case, dummy0 is supposed to drop the packets. But with
>> macvlan these packets are broadcasted to the other macvlan ports, so no
>> checksum is computed when the packets are transmitted between macvlan1
>> and macvlan2.
> So where frames get bad checksums ?
>
> In this "bridge" mode, I suspect the broadcast is done _before_ sending
> frame to dummy, so maybe macvlan should not inherit from lowerdev in
> this particular case ?
Hi Eric,
yes, you are right, the packets are sent before.
In the 'macvlan_queue_xmit', the code checks the dev is in 'bridge'
mode. If so, it looks if there is a destination port for the packet and
then calls the 'forward' callback which is 'dev_forward_skb'.
I was able to reproduce the same problem with qemu and an emulated
'e1000' card instead of dummy0. The packets are dropped too.
Patrick, do you have any suggestions to fix this ?
Thanks
-- Daniel
^ permalink raw reply
* Re: [GIT/PATCH v3] xen network backend driver
From: Ian Campbell @ 2011-03-01 13:38 UTC (permalink / raw)
To: Ben Hutchings
Cc: netdev@vger.kernel.org, xen-devel, Jeremy Fitzhardinge,
Herbert Xu, Konrad Rzeszutek Wilk, Francois Romieu
In-Reply-To: <1298982526.3437.5.camel@localhost>
On Tue, 2011-03-01 at 12:28 +0000, Ben Hutchings wrote:
> On Tue, 2011-03-01 at 10:06 +0000, Ian Campbell wrote:
> > On Mon, 2011-02-28 at 18:53 +0000, Ben Hutchings wrote:
> > > On Mon, 2011-02-28 at 17:27 +0000, Ian Campbell wrote:
> >
> > > This should be defined as unsigned long (ideally it would be u64, but
> > > that can't be updated atomically on 32-bit systems).
> > [...]
> > > Don't update last_rx; it's only needed on slave devices of a bond, and
> > > the bonding driver takes care of it now.
> >
> > I made these two changes.
> >
> > > [...]
> > > > +static int xenvif_change_mtu(struct net_device *dev, int mtu)
> > > > +{
> > > > + struct xenvif *vif = netdev_priv(dev);
> > > > + int max = vif->can_sg ? 65535 - ETH_HLEN : ETH_DATA_LEN;
> > > > + if (mtu > max)
> > > > + return -EINVAL;
> > > > + dev->mtu = mtu;
> > > > + return 0;
> > > > +}
> > > [...]
> > >
> > > Since any VLAN tag must be inserted inline, shouldn't the MTU limit be
> > > 65535 - VLAN_ETH_HLEN?
> >
> > In that case shouldn't the other case also be ETH_FRAME_LEN -
> > VLAN_ETH_HLEN?
> [...]
>
> IEEE 802.3, in its infinite wisdom, says that the maximum frame length
> is 1514, except that when an 802.1q tag is present it is 1518. So the
> MTU for standard Ethernet remains 1500, regardless of the use of VLANs.
Super ;-)
I've made that change too and repushed the branch with all 3 of your
suggestions. The incremental patch is below.
The following changes since commit 2e820f58f7ad8eaca2f194ccdfea0de63e9c6d78:
Ian Campbell (1):
xen/irq: implement bind_interdomain_evtchn_to_irqhandler for backend drivers
are available in the git repository at:
git://xenbits.xen.org/people/ianc/linux-2.6.git upstream/dom0/backend/netback
Bastian Blank (1):
xen: netback: Fix null-pointer access in netback_uevent
Christophe Saout (1):
xen: netback: use dev_name() instead of removed ->bus_id.
Dongxiao Xu (5):
xen: netback: Move global/static variables into struct xen_netbk.
xen: netback: Introduce a new struct type page_ext.
xen: netback: Multiple tasklets support.
xen: netback: Use Kernel thread to replace the tasklet.
xen: netback: Set allocated memory to zero from vmalloc.
Ian Campbell (61):
xen: netback: Initial import of linux-2.6.18-xen.hg netback driver.
xen: netback: first cut at porting to upstream and cleaning up
xen: netback: add ethtool stat to track copied skbs.
xen: netback: make queue length parameter writeable in sysfs
xen: netback: parent sysfs device should be set before registering.
xen: rename netbk module xen-netback.
xen: netback: remove unused xen_network_done code
xen: netback: factor disconnect from backend into new function.
xen: netback: wait for hotplug scripts to complete before signalling connected to frontend
xen: netback: Always pull through PKT_PROT_LEN bytes into the linear part of an skb.
xen: netback: Allow setting of large MTU before rings have connected.
xen: netback: correctly setup skb->ip_summed on receive
xen: netback: handle NET_SKBUFF_DATA_USES_OFFSET correctly
xen: netback: drop frag member from struct netbk_rx_meta
xen: netback: linearise SKBs as we copy them into guest memory on guest-RX.
xen: netback: drop more relics of flipping mode
xen: netback: check if foreign pages are actually netback-created foreign pages.
xen: netback: do not unleash netback threads until initialisation is complete
xen: netback: save interrupt state in add_to_net_schedule_list_tail
xen: netback: increase size of rx_meta array.
xen: netback: take net_schedule_list_lock when removing entry from net_schedule_list
xen: netback: Drop GSO SKBs which do not have csum_blank.
xen: netback: completely remove tx_queue_timer
Revert "xen: netback: Drop GSO SKBs which do not have csum_blank."
xen: netback: handle incoming GSO SKBs which are not CHECKSUM_PARTIAL
xen: netback: rationalise types used in count_skb_slots
xen: netback: refactor logic for moving to a new receive buffer.
xen: netback: refactor code to get next rx buffer into own function.
xen: netback: simplify use of netbk_add_frag_responses
xen: netback: cleanup coding style
xen: netback: drop private ?PRINTK macros in favour of pr_*
xen: netback: move under drivers/net/xen-netback/
xen: netback: remove queue_length module option
xen: netback: correct error return from ethtool hooks.
xen: netback: avoid leading _ in function parameter names.
xen: netback: drop unused debug interrupt handler.
xen: netif: properly namespace the Xen netif protocol header.
xen: netif: improve Kconfig help text for front- and backend drivers.
xen: netback: drop ethtool drvinfo callback
xen: netback: use xen_netbk prefix where appropriate
xen: netback: refactor to make all xen_netbk knowledge internal to netback.c
xen: netback: use xenvif_ prefix where appropriate
xen: netback: add reference from xenvif to xen_netbk
xen: netback: refactor to separate network device from worker pools
xen: netback: switch to kthread mode and drop tasklet mode
xen: netback: handle frames whose head crosses a page boundary
xen: netback: return correct values from start_xmit
xen: netback: remove useless memset to zero.
xen: netback: use register_netdev()
xen: netback: simplify unwinding netback_init's work on failure.
xen: netback: use core network carrier flag.
xen: netback: s/xenvif_queue_full/xenvif_rx_queue_full/
xen: netback: add xenvif_rx_schedulable
xen: netback: further separate xen_netbk and xenvif
xen: netback: use netdev_LEVEL instead of pr_LEVEL
xen: netback: drop rx_notify and notify_list array in favour of a normal list
xen: netback: Make dependency on PageForeign conditional
xen: netback: completely drop foreign page support
xen: netback: ethtool stats fields should be unsigned long
xen: netback: do not update last_rx on receive.
xen: netback: Allow headroom for VLAN header in SG MTU calculation.
James Harper (1):
xen: netback: avoid null-pointer access in netback_uevent
Jan Beulich (1):
xen: netback: unmap tx ring gref when mapping of rx ring gref failed
Jeremy Fitzhardinge (21):
xen: netback: don't include xen/evtchn.h
xen: netback: use mod_timer
xen: netback: use NET_SKB_PAD rather than "16"
xen: netback: completely drop flip support
xen: netback: demacro MASK_PEND_IDX
xen: netback: convert PEND_RING_IDX into a proper typedef name
xen: netback: rename NR_PENDING_REQS to nr_pending_reqs()
xen: netback: pre-initialize list and spinlocks; use empty list to indicate not on list
xen: netback: remove CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER
xen: netback: make netif_get/put inlines
xen: netback: move code around
xen: netback: document PKT_PROT_LEN
xen: netback: convert to net_device_ops
xen: netback: reinstate missing code
xen: netback: remove debug noise
xen: netback: don't screw around with packet gso state
xen: netback: use dev_get/set_drvdata() inteface
xen: netback: include linux/sched.h for TASK_* definitions
xen: netback: use get_sset_count rather than obsolete get_stats_count
xen: netback: minor code formatting fixup
xen: netback: only initialize for PV domains
Keir Fraser (1):
xen: netback: Fixes for delayed copy of tx network packets.
Konrad Rzeszutek Wilk (1):
Fix compile warnings: ignoring return value of 'xenbus_register_backend' ..
Paul Durrant (8):
xen: netback: Fix basic indentation issue
xen: netback: Add a new style of passing GSO packets to frontends.
xen: netback: Make frontend features distinct from netback feature flags.
xen: netback: Re-define PKT_PROT_LEN to be bigger.
xen: netback: Don't count packets we don't actually receive.
xen: netback: Remove the 500ms timeout to restart the netif queue.
xen: netback: Add a missing test to tx_work_todo.
xen: netback: Re-factor net_tx_action_dealloc() slightly.
Steven Smith (2):
xen: netback: make sure that pg->mapping is never NULL for a page mapped from a foreign domain.
xen: netback: try to pull a minimum of 72 bytes into the skb data area
drivers/net/Kconfig | 38 +-
drivers/net/Makefile | 1 +
drivers/net/xen-netback/Makefile | 3 +
drivers/net/xen-netback/common.h | 162 ++++
drivers/net/xen-netback/interface.c | 424 +++++++++
drivers/net/xen-netback/netback.c | 1745 +++++++++++++++++++++++++++++++++++
drivers/net/xen-netback/xenbus.c | 490 ++++++++++
drivers/net/xen-netfront.c | 20 +-
include/xen/interface/io/netif.h | 80 +-
9 files changed, 2909 insertions(+), 54 deletions(-)
create mode 100644 drivers/net/xen-netback/Makefile
create mode 100644 drivers/net/xen-netback/common.h
create mode 100644 drivers/net/xen-netback/interface.c
create mode 100644 drivers/net/xen-netback/netback.c
create mode 100644 drivers/net/xen-netback/xenbus.c
Ian.
diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h
index 21f4c0c..406fbef 100644
--- a/drivers/net/xen-netback/common.h
+++ b/drivers/net/xen-netback/common.h
@@ -99,7 +99,7 @@ struct xenvif {
struct timer_list credit_timeout;
/* Statistics */
- int rx_gso_checksum_fixup;
+ unsigned long rx_gso_checksum_fixup;
/* Miscellaneous private stuff. */
struct list_head schedule_list;
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index 1614ba5..887e2ce 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -32,6 +32,7 @@
#include <linux/ethtool.h>
#include <linux/rtnetlink.h>
+#include <linux/if_vlan.h>
#include <xen/events.h>
#include <asm/xen/hypercall.h>
@@ -107,7 +108,6 @@ static int xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev)
void xenvif_receive_skb(struct xenvif *vif, struct sk_buff *skb)
{
netif_rx_ni(skb);
- vif->dev->last_rx = jiffies;
}
void xenvif_notify_tx_completion(struct xenvif *vif)
@@ -157,7 +157,7 @@ static int xenvif_close(struct net_device *dev)
static int xenvif_change_mtu(struct net_device *dev, int mtu)
{
struct xenvif *vif = netdev_priv(dev);
- int max = vif->can_sg ? 65535 - ETH_HLEN : ETH_DATA_LEN;
+ int max = vif->can_sg ? 65535 - VLAN_ETH_HLEN : ETH_DATA_LEN;
if (mtu > max)
return -EINVAL;
^ permalink raw reply related
* Re: SO_REUSEPORT - can it be done in kernel?
From: Thomas Graf @ 2011-03-01 13:50 UTC (permalink / raw)
To: Herbert Xu
Cc: Eric Dumazet, David Miller, rick.jones2, therbert, wsommerfeld,
daniel.baluta, netdev
In-Reply-To: <20110301121951.GA7267@gondor.apana.org.au>
On Tue, Mar 01, 2011 at 08:19:51PM +0800, Herbert Xu wrote:
> On Tue, Mar 01, 2011 at 07:18:29AM -0500, Thomas Graf wrote:
> >
> >
> > ... makes it use CPU 5 for rxq2 and the qps goes up from 250kqps to 270kqps
>
> I think the increase here comes from the larger number of packets
> in flight more than anything.
>
> The bottleneck is still the TX queue (both software and hardware).
Disabled netfilter and reran test
Now does ~316kqps (rx was split over 2 queues)
----------------------------------------------------------------------------------------------------------------------
PerfTop: 30608 irqs/sec kernel:66.1% exact: 0.0% [1000Hz cpu-clock-msecs], (all, CPU: 1)
----------------------------------------------------------------------------------------------------------------------
samples pcnt function DSO
_______ _____ _____________________________ ___________________________________________________________
19237.00 5.6% _raw_spin_unlock_irqrestore /lib/modules/2.6.38-rc5+/build/vmlinux
17170.00 5.0% get_rx_page_info /lib/modules/2.6.38-rc5+/kernel/drivers/net/benet/be2net.ko
11411.00 3.3% be_poll_rx /lib/modules/2.6.38-rc5+/kernel/drivers/net/benet/be2net.ko
11320.00 3.3% isc_rwlock_lock /usr/lib64/libisc.so.62.0.1
10669.00 3.1% __do_softirq /lib/modules/2.6.38-rc5+/build/vmlinux
10655.00 3.1% get_page_from_freelist /lib/modules/2.6.38-rc5+/build/vmlinux
9523.00 2.8% intel_idle /lib/modules/2.6.38-rc5+/build/vmlinux
8677.00 2.5% __udp4_lib_lookup /lib/modules/2.6.38-rc5+/build/vmlinux
8379.00 2.4% sock_queue_rcv_skb /lib/modules/2.6.38-rc5+/build/vmlinux
8226.00 2.4% sk_run_filter /lib/modules/2.6.38-rc5+/build/vmlinux
6724.00 1.9% __netif_receive_skb /lib/modules/2.6.38-rc5+/build/vmlinux
6553.00 1.9% __alloc_skb /lib/modules/2.6.38-rc5+/build/vmlinux
6205.00 1.8% udp_queue_rcv_skb /lib/modules/2.6.38-rc5+/build/vmlinux
6038.00 1.7% _raw_spin_lock /lib/modules/2.6.38-rc5+/build/vmlinux
5868.00 1.7% isc_rwlock_unlock /usr/lib64/libisc.so.62.0.1
5696.00 1.6% dns_rbt_findnode /usr/lib64/libdns.so.69.0.1
5647.00 1.6% read_tsc /lib/modules/2.6.38-rc5+/build/vmlinux
5633.00 1.6% getnstimeofday /lib/modules/2.6.38-rc5+/build/vmlinux
5448.00 1.6% kmem_cache_alloc_node_trace /lib/modules/2.6.38-rc5+/build/vmlinux
5272.00 1.5% finish_task_switch /lib/modules/2.6.38-rc5+/build/vmlinux
4719.00 1.4% sock_def_readable /lib/modules/2.6.38-rc5+/build/vmlinux
4002.00 1.2% is_swiotlb_buffer /lib/modules/2.6.38-rc5+/build/vmlinux
3914.00 1.1% memcpy /lib/modules/2.6.38-rc5+/build/vmlinux
3717.00 1.1% isc_stats_increment /usr/lib64/libisc.so.62.0.1
3706.00 1.1% __udp4_lib_rcv /lib/modules/2.6.38-rc5+/build/vmlinux
3653.00 1.1% ip_rcv /lib/modules/2.6.38-rc5+/build/vmlinux
3598.00 1.0% kmem_cache_alloc_node /lib/modules/2.6.38-rc5+/build/vmlinux
3407.00 1.0% ip_route_input_common /lib/modules/2.6.38-rc5+/build/vmlinux
2683.00 0.8% be_post_rx_frags /lib/modules/2.6.38-rc5+/kernel/drivers/net/benet/be2net.ko
2666.00 0.8% __pthread_mutex_lock_internal /lib64/libpthread-2.12.so
2331.00 0.7% __phys_addr /lib/modules/2.6.38-rc5+/build/vmlinux
2230.00 0.6% __alloc_pages_nodemask /lib/modules/2.6.38-rc5+/build/vmlinux
2023.00 0.6% dns_name_fullcompare /usr/lib64/libdns.so.69.0.1
1972.00 0.6% packet_rcv /lib/modules/2.6.38-rc5+/build/vmlinux
1902.00 0.6% eth_type_trans /lib/modules/2.6.38-rc5+/build/vmlinux
1860.00 0.5% __pthread_mutex_unlock /lib64/libpthread-2.12.so
1804.00 0.5% fget_light /lib/modules/2.6.38-rc5+/build/vmlinux
1739.00 0.5% alloc_pages_current /lib/modules/2.6.38-rc5+/build/vmlinux
1736.00 0.5% dns_rbtnodechain_init /usr/lib64/libdns.so.69.0.1
----------------------------------------------------------------------------------------------------------------------
PerfTop: 29038 irqs/sec kernel:48.0% exact: 0.0% [1000Hz cpu-clock-msecs], (all, CPU: 11)
----------------------------------------------------------------------------------------------------------------------
samples pcnt function DSO
_______ _____ _____________________________ ___________________________________________________________
12833.00 7.5% intel_idle /lib/modules/2.6.38-rc5+/build/vmlinux
10771.00 6.3% isc_rwlock_lock /usr/lib64/libisc.so.62.0.1
8713.00 5.1% be_tx_compl_process /lib/modules/2.6.38-rc5+/kernel/drivers/net/benet/be2net.ko
6452.00 3.8% kfree /lib/modules/2.6.38-rc5+/build/vmlinux
5935.00 3.5% skb_release_data /lib/modules/2.6.38-rc5+/build/vmlinux
5552.00 3.2% kmem_cache_free /lib/modules/2.6.38-rc5+/build/vmlinux
5292.00 3.1% isc_rwlock_unlock /usr/lib64/libisc.so.62.0.1
4893.00 2.9% dns_rbt_findnode /usr/lib64/libdns.so.69.0.1
4413.00 2.6% kfree_skb /lib/modules/2.6.38-rc5+/build/vmlinux
3802.00 2.2% be_poll_tx_mcc /lib/modules/2.6.38-rc5+/kernel/drivers/net/benet/be2net.ko
3515.00 2.1% isc_stats_increment /usr/lib64/libisc.so.62.0.1
3016.00 1.8% _raw_spin_unlock_irqrestore /lib/modules/2.6.38-rc5+/build/vmlinux
2202.00 1.3% __do_softirq /lib/modules/2.6.38-rc5+/build/vmlinux
2027.00 1.2% _raw_spin_lock /lib/modules/2.6.38-rc5+/build/vmlinux
1935.00 1.1% finish_task_switch /lib/modules/2.6.38-rc5+/build/vmlinux
1906.00 1.1% __pthread_mutex_lock_internal /lib64/libpthread-2.12.so
1837.00 1.1% dns_name_fullcompare /usr/lib64/libdns.so.69.0.1
1702.00 1.0% dns_rbtnodechain_init /usr/lib64/libdns.so.69.0.1
1561.00 0.9% fget_light /lib/modules/2.6.38-rc5+/build/vmlinux
1559.00 0.9% dns_name_getlabelsequence /usr/lib64/libdns.so.69.0.1
1491.00 0.9% dns_name_equal /usr/lib64/libdns.so.69.0.1
1464.00 0.9% __pthread_mutex_unlock /lib64/libpthread-2.12.so
1454.00 0.9% dns_acl_match /usr/lib64/libdns.so.69.0.1
1293.00 0.8% dns_zone_attach /usr/lib64/libdns.so.69.0.1
1245.00 0.7% be_xmit /lib/modules/2.6.38-rc5+/kernel/drivers/net/benet/be2net.ko
1159.00 0.7% dns_message_rendersection /usr/lib64/libdns.so.69.0.1
1115.00 0.7% isc___mempool_get /usr/lib64/libisc.so.62.0.1
1100.00 0.6% copy_user_generic_string /lib/modules/2.6.38-rc5+/build/vmlinux
1030.00 0.6% dns_name_fromwire /usr/lib64/libdns.so.69.0.1
1015.00 0.6% dns_name_hash /usr/lib64/libdns.so.69.0.1
1013.00 0.6% isc_radix_search /usr/lib64/libisc.so.62.0.1
970.00 0.6% __ip_route_output_key /lib/modules/2.6.38-rc5+/build/vmlinux
917.00 0.5% fput /lib/modules/2.6.38-rc5+/build/vmlinux
817.00 0.5% dev_queue_xmit /lib/modules/2.6.38-rc5+/build/vmlinux
812.00 0.5% sk_run_filter /lib/modules/2.6.38-rc5+/build/vmlinux
806.00 0.5% avc_has_perm_noaudit /lib/modules/2.6.38-rc5+/build/vmlinux
802.00 0.5% sock_wfree /lib/modules/2.6.38-rc5+/build/vmlinux
793.00 0.5% dns_name_towire /usr/lib64/libdns.so.69.0.1
754.00 0.4% sock_alloc_send_pskb /lib/modules/2.6.38-rc5+/build/vmlinux
752.00 0.4% dns_message_parse /usr/lib64/libdns.so.69.0.1
749.00 0.4% dns_rdata_towire /usr/lib64/libdns.so.69.0.1
728.00 0.4% dns_rdataset_init /usr/lib64/libdns.so.69.0.1
709.00 0.4% isc___mempool_put /usr/lib64/libisc.so.62.0.1
699.00 0.4% skb_release_head_state /lib/modules/2.6.38-rc5+/build/vmlinux
685.00 0.4% _raw_spin_lock_bh /lib/modules/2.6.38-rc5+/build/vmlinux
683.00 0.4% dns_name_concatenate /usr/lib64/libdns.so.69.0.1
678.00 0.4% __ip_append_data /lib/modules/2.6.38-rc5+/build/vmlinux
673.00 0.4% tick_nohz_stop_sched_tick /lib/modules/2.6.38-rc5+/build/vmlinux
662.00 0.4% sys_sendmsg /lib/modules/2.6.38-rc5+/build/vmlinux
654.00 0.4% dns_compress_findglobal /usr/lib64/libdns.so.69.0.1
654.00 0.4% memcpy /lib64/libc-2.12.so
637.00 0.4% dns_compress_invalidate /usr/lib64/libdns.so.69.0.1
597.00 0.3% isc__buffer_init /usr/lib64/libisc.so.62.0.1
595.00 0.3% dns_zone_detach /usr/lib64/libdns.so.69.0.1
WARNING: failed to keep up with mmap data.
WARNING: failed to keep up with mmap data.
----------------------------------------------------------------------------------------------------------------------
PerfTop: 29539 irqs/sec kernel:47.0% exact: 0.0% [1000Hz cpu-clock-msecs], (all, CPU: 11)
----------------------------------------------------------------------------------------------------------------------
samples pcnt function DSO
_______ _____ _____________________________ ___________________________________________________________
14478.00 7.5% intel_idle /lib/modules/2.6.38-rc5+/build/vmlinux
12279.00 6.3% isc_rwlock_lock /usr/lib64/libisc.so.62.0.1
9844.00 5.1% be_tx_compl_process /lib/modules/2.6.38-rc5+/kernel/drivers/net/benet/be2net.ko
7368.00 3.8% kfree /lib/modules/2.6.38-rc5+/build/vmlinux
6696.00 3.5% skb_release_data /lib/modules/2.6.38-rc5+/build/vmlinux
6240.00 3.2% kmem_cache_free /lib/modules/2.6.38-rc5+/build/vmlinux
6034.00 3.1% isc_rwlock_unlock /usr/lib64/libisc.so.62.0.1
5547.00 2.9% dns_rbt_findnode /usr/lib64/libdns.so.69.0.1
5012.00 2.6% kfree_skb /lib/modules/2.6.38-rc5+/build/vmlinux
4290.00 2.2% be_poll_tx_mcc /lib/modules/2.6.38-rc5+/kernel/drivers/net/benet/be2net.ko
4024.00 2.1% isc_stats_increment /usr/lib64/libisc.so.62.0.1
3417.00 1.8% _raw_spin_unlock_irqrestore /lib/modules/2.6.38-rc5+/build/vmlinux
2470.00 1.3% __do_softirq /lib/modules/2.6.38-rc5+/build/vmlinux
2312.00 1.2% _raw_spin_lock /lib/modules/2.6.38-rc5+/build/vmlinux
2138.00 1.1% finish_task_switch /lib/modules/2.6.38-rc5+/build/vmlinux
2136.00 1.1% __pthread_mutex_lock_internal /lib64/libpthread-2.12.so
2061.00 1.1% dns_name_fullcompare /usr/lib64/libdns.so.69.0.1
1961.00 1.0% dns_rbtnodechain_init /usr/lib64/libdns.so.69.0.1
1797.00 0.9% dns_name_getlabelsequence /usr/lib64/libdns.so.69.0.1
1743.00 0.9% fget_light /lib/modules/2.6.38-rc5+/build/vmlinux
1723.00 0.9% dns_name_equal /usr/lib64/libdns.so.69.0.1
1673.00 0.9% __pthread_mutex_unlock /lib64/libpthread-2.12.so
1671.00 0.9% dns_acl_match /usr/lib64/libdns.so.69.0.1
1488.00 0.8% dns_zone_attach /usr/lib64/libdns.so.69.0.1
1428.00 0.7% be_xmit /lib/modules/2.6.38-rc5+/kernel/drivers/net/benet/be2net.ko
1369.00 0.7% dns_message_rendersection /usr/lib64/libdns.so.69.0.1
1278.00 0.7% isc___mempool_get /usr/lib64/libisc.so.62.0.1
1251.00 0.6% copy_user_generic_string /lib/modules/2.6.38-rc5+/build/vmlinux
1193.00 0.6% dns_name_fromwire /usr/lib64/libdns.so.69.0.1
1182.00 0.6% isc_radix_search /usr/lib64/libisc.so.62.0.1
^ permalink raw reply
* Re: SO_REUSEPORT - can it be done in kernel?
From: Eric Dumazet @ 2011-03-01 13:52 UTC (permalink / raw)
To: Herbert Xu
Cc: Thomas Graf, David Miller, rick.jones2, therbert, wsommerfeld,
daniel.baluta, netdev
In-Reply-To: <20110301131823.GB8028@gondor.apana.org.au>
Le mardi 01 mars 2011 à 21:18 +0800, Herbert Xu a écrit :
> Interesting. So I wonder which lock is showing up at the top
> of the profile with a single socket then. As it's definitely
> going away with multiple sockets, that means it's not the TX
> queue lock.
>
This CPU also runs named process, so this is socket lock and receive
queue lock.
Named threads all do : recvmsg()/sendmsg() in a loop, so all are waiting
a frame before doing some work.
Because of single receive queue, extra context switches occur (all
threads but one have to sleep again per query)
For about 80 kqps (standard linux-2.6 kernel, no patches), I have
following vmstat output
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
4 1 0 2184048 63496 1595056 0 0 0 2060 64592 294528 19 11 67 4
6 1 0 2184040 63496 1595056 0 0 0 1960 64686 293928 19 11 66 4
3 1 0 2184040 63496 1595056 0 0 0 2344 64556 294268 20 11 66 4
4 1 0 2184040 63496 1595056 0 0 0 2400 64626 293859 19 11 67 4
^ permalink raw reply
* Re: SO_REUSEPORT - can it be done in kernel?
From: Herbert Xu @ 2011-03-01 13:58 UTC (permalink / raw)
To: Eric Dumazet
Cc: Thomas Graf, David Miller, rick.jones2, therbert, wsommerfeld,
daniel.baluta, netdev
In-Reply-To: <1298987566.3284.105.camel@edumazet-laptop>
On Tue, Mar 01, 2011 at 02:52:46PM +0100, Eric Dumazet wrote:
> Le mardi 01 mars 2011 à 21:18 +0800, Herbert Xu a écrit :
>
> > Interesting. So I wonder which lock is showing up at the top
> > of the profile with a single socket then. As it's definitely
> > going away with multiple sockets, that means it's not the TX
> > queue lock.
> >
>
> This CPU also runs named process, so this is socket lock and receive
> queue lock.
It can't be the socket lock because it's an IRQ-disabling variant.
The receive queue lock, I'll buy that.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: SO_REUSEPORT - can it be done in kernel?
From: Eric Dumazet @ 2011-03-01 14:06 UTC (permalink / raw)
To: Thomas Graf
Cc: Herbert Xu, David Miller, rick.jones2, therbert, wsommerfeld,
daniel.baluta, netdev
In-Reply-To: <20110301135053.GA6684@canuck.infradead.org>
Le mardi 01 mars 2011 à 08:50 -0500, Thomas Graf a écrit :
> On Tue, Mar 01, 2011 at 08:19:51PM +0800, Herbert Xu wrote:
> > On Tue, Mar 01, 2011 at 07:18:29AM -0500, Thomas Graf wrote:
> > >
> > >
> > > ... makes it use CPU 5 for rxq2 and the qps goes up from 250kqps to 270kqps
> >
> > I think the increase here comes from the larger number of packets
> > in flight more than anything.
> >
> > The bottleneck is still the TX queue (both software and hardware).
>
> Disabled netfilter and reran test
>
> Now does ~316kqps (rx was split over 2 queues)
Would be nice to cpu affine named to _not_ run on CPU11, just to
specialize it for TX completions and have softirq time percentage and
"perf top -C 11 " results
Thanks
^ permalink raw reply
* Re: [PATCH]drivers:isdn:istream.c Fix typo pice to piece
From: Jiri Kosina @ 2011-03-01 14:21 UTC (permalink / raw)
To: Justin P. Mattock; +Cc: mac, isdn, netdev, linux-kernel
In-Reply-To: <1298269881-2754-1-git-send-email-justinmattock@gmail.com>
On Sun, 20 Feb 2011, Justin P. Mattock wrote:
> The below patch changes a typo "pice" to "piece"
>
> Signed-off-by: Justin P. Mattock <justinmattock@gmail.com>
>
> ---
> drivers/isdn/hardware/eicon/istream.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/isdn/hardware/eicon/istream.c b/drivers/isdn/hardware/eicon/istream.c
> index 18f8798..7bd5baa 100644
> --- a/drivers/isdn/hardware/eicon/istream.c
> +++ b/drivers/isdn/hardware/eicon/istream.c
> @@ -62,7 +62,7 @@ void diva_xdi_provide_istream_info (ADAPTER* a,
> stream interface.
> If synchronous service was requested, then function
> does return amount of data written to stream.
> - 'final' does indicate that pice of data to be written is
> + 'final' does indicate that piece of data to be written is
> final part of frame (necessary only by structured datatransfer)
> return 0 if zero lengh packet was written
> return -1 if stream is full
Applied.
--
Jiri Kosina
SUSE Labs, Novell Inc.
^ permalink raw reply
* Re: SO_REUSEPORT - can it be done in kernel?
From: Thomas Graf @ 2011-03-01 14:22 UTC (permalink / raw)
To: Eric Dumazet
Cc: Herbert Xu, David Miller, rick.jones2, therbert, wsommerfeld,
daniel.baluta, netdev
In-Reply-To: <1298988419.3284.107.camel@edumazet-laptop>
On Tue, Mar 01, 2011 at 03:06:59PM +0100, Eric Dumazet wrote:
> Would be nice to cpu affine named to _not_ run on CPU11, just to
> specialize it for TX completions and have softirq time percentage and
> "perf top -C 11 " results
----------------------------------------------------------------------------------------------------------------------
PerfTop: 995 irqs/sec kernel:97.7% exact: 0.0% [1000Hz cpu-clock-msecs], (all, CPU: 11)
----------------------------------------------------------------------------------------------------------------------
samples pcnt function DSO
_______ _____ ___________________________ ___________________________________________________________
335.00 23.3% intel_idle /lib/modules/2.6.38-rc5+/build/vmlinux
253.00 17.6% be_tx_compl_process /lib/modules/2.6.38-rc5+/kernel/drivers/net/benet/be2net.ko
177.00 12.3% skb_release_data /lib/modules/2.6.38-rc5+/build/vmlinux
132.00 9.2% kfree /lib/modules/2.6.38-rc5+/build/vmlinux
127.00 8.8% kfree_skb /lib/modules/2.6.38-rc5+/build/vmlinux
105.00 7.3% be_poll_tx_mcc /lib/modules/2.6.38-rc5+/kernel/drivers/net/benet/be2net.ko
99.00 6.9% kmem_cache_free /lib/modules/2.6.38-rc5+/build/vmlinux
36.00 2.5% __do_softirq /lib/modules/2.6.38-rc5+/build/vmlinux
20.00 1.4% _raw_spin_unlock_irqrestore /lib/modules/2.6.38-rc5+/build/vmlinux
19.00 1.3% skb_release_head_state /lib/modules/2.6.38-rc5+/build/vmlinux
13.00 0.9% unmap_tx_frag /lib/modules/2.6.38-rc5+/kernel/drivers/net/benet/be2net.ko
11.00 0.8% rb_next /usr/bin/perf
10.00 0.7% dso__find_symbol /usr/bin/perf
9.00 0.6% is_swiotlb_buffer /lib/modules/2.6.38-rc5+/build/vmlinux
9.00 0.6% __strcmp_sse42 /lib64/libc-2.12.so
8.00 0.6% __kfree_skb /lib/modules/2.6.38-rc5+/build/vmlinux
8.00 0.6% __strstr_sse42 /lib64/libc-2.12.so
6.00 0.4% _int_malloc /lib64/libc-2.12.so
^ permalink raw reply
* Re: SO_REUSEPORT - can it be done in kernel?
From: Thomas Graf @ 2011-03-01 14:30 UTC (permalink / raw)
To: Eric Dumazet, Herbert Xu, David Miller, rick.jones2, therbert,
wsommerfeld
In-Reply-To: <20110301142235.GA10761@canuck.infradead.org>
On Tue, Mar 01, 2011 at 09:22:35AM -0500, Thomas Graf wrote:
> On Tue, Mar 01, 2011 at 03:06:59PM +0100, Eric Dumazet wrote:
> > Would be nice to cpu affine named to _not_ run on CPU11, just to
> > specialize it for TX completions and have softirq time percentage and
> > "perf top -C 11 " results
CPU 1 isolated as well (named running with mask 0,2-10)
----------------------------------------------------------------------------------------------------------------------
PerfTop: 580 irqs/sec kernel:100.0% exact: 0.0% [1000Hz cpu-clock-msecs], (all, CPU: 1)
----------------------------------------------------------------------------------------------------------------------
samples pcnt function DSO
_______ _____ ___________________________ ___________________________________________________________
283.00 9.2% get_rx_page_info /lib/modules/2.6.38-rc5+/kernel/drivers/net/benet/be2net.ko
256.00 8.4% _raw_spin_unlock_irqrestore /lib/modules/2.6.38-rc5+/build/vmlinux
190.00 6.2% be_poll_rx /lib/modules/2.6.38-rc5+/kernel/drivers/net/benet/be2net.ko
182.00 5.9% get_page_from_freelist /lib/modules/2.6.38-rc5+/build/vmlinux
157.00 5.1% intel_idle /lib/modules/2.6.38-rc5+/build/vmlinux
143.00 4.7% __do_softirq /lib/modules/2.6.38-rc5+/build/vmlinux
133.00 4.3% sock_queue_rcv_skb /lib/modules/2.6.38-rc5+/build/vmlinux
133.00 4.3% __udp4_lib_lookup /lib/modules/2.6.38-rc5+/build/vmlinux
131.00 4.3% sk_run_filter /lib/modules/2.6.38-rc5+/build/vmlinux
114.00 3.7% getnstimeofday /lib/modules/2.6.38-rc5+/build/vmlinux
112.00 3.7% __alloc_skb /lib/modules/2.6.38-rc5+/build/vmlinux
103.00 3.4% read_tsc /lib/modules/2.6.38-rc5+/build/vmlinux
100.00 3.3% __netif_receive_skb /lib/modules/2.6.38-rc5+/build/vmlinux
95.00 3.1% udp_queue_rcv_skb /lib/modules/2.6.38-rc5+/build/vmlinux
82.00 2.7% sock_def_readable /lib/modules/2.6.38-rc5+/build/vmlinux
79.00 2.6% kmem_cache_alloc_node_trace /lib/modules/2.6.38-rc5+/build/vmlinux
72.00 2.3% _raw_spin_lock /lib/modules/2.6.38-rc5+/build/vmlinux
67.00 2.2% __phys_addr /lib/modules/2.6.38-rc5+/build/vmlinux
63.00 2.1% is_swiotlb_buffer /lib/modules/2.6.38-rc5+/build/vmlinux
51.00 1.7% __udp4_lib_rcv /lib/modules/2.6.38-rc5+/build/vmlinux
48.00 1.6% memcpy /lib/modules/2.6.38-rc5+/build/vmlinux
47.00 1.5% ip_rcv /lib/modules/2.6.38-rc5+/build/vmlinux
46.00 1.5% kmem_cache_alloc_node /lib/modules/2.6.38-rc5+/build/vmlinux
44.00 1.4% dma_issue_pending_all /lib/modules/2.6.38-rc5+/build/vmlinux
40.00 1.3% ip_route_input_common /lib/modules/2.6.38-rc5+/build/vmlinux
36.00 1.2% __alloc_pages_nodemask /lib/modules/2.6.38-rc5+/build/vmlinux
33.00 1.1% be_post_rx_frags /lib/modules/2.6.38-rc5+/kernel/drivers/net/benet/be2net.ko
24.00 0.8% alloc_pages_current /lib/modules/2.6.38-rc5+/build/vmlinux
21.00 0.7% packet_rcv /lib/modules/2.6.38-rc5+/build/vmlinux
20.00 0.7% local_bh_enable /lib/modules/2.6.38-rc5+/build/vmlinux
17.00 0.6% consume_skb /lib/modules/2.6.38-rc5+/build/vmlinux
16.00 0.5% next_zones_zonelist /lib/modules/2.6.38-rc5+/build/vmlinux
14.00 0.5% selinux_socket_sock_rcv_skb /lib/modules/2.6.38-rc5+/build/vmlinux
13.00 0.4% ip_local_deliver /lib/modules/2.6.38-rc5+/build/vmlinux
11.00 0.4% sk_filter /lib/modules/2.6.38-rc5+/build/vmlinux
10.00 0.3% get_rps_cpu /lib/modules/2.6.38-rc5+/build/vmlinux
9.00 0.3% native_read_tsc /lib/modules/2.6.38-rc5+/build/vmlinux
8.00 0.3% local_bh_disable /lib/modules/2.6.38-rc5+/build/vmlinux
8.00 0.3% eth_type_trans /lib/modules/2.6.38-rc5+/build/vmlinux
8.00 0.3% napi_complete /lib/modules/2.6.38-rc5+/build/vmlinux
7.00 0.2% netif_receive_skb /lib/modules/2.6.38-rc5+/build/vmlinux
7.00 0.2% dso__find_symbol /usr/bin/perf
7.00 0.2% __kmalloc_node_track_caller /lib/modules/2.6.38-rc5+/build/vmlinux
^ 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