Netdev List
 help / color / mirror / Atom feed
* [PATCH v16 00/17] Provide a zero-copy method on KVM virtio-net.
From: xiaohui.xin @ 2010-12-01  8:08 UTC (permalink / raw)
  To: netdev, kvm, linux-kernel, mst, mingo, davem, herbert, jdike
In-Reply-To: <fc6e95d63a2c62aaf77f8ded22fc43ccefcdbbff.1291187695.git.xiaohui.xin@intel.com>

We provide an zero-copy method which driver side may get external
buffers to DMA. Here external means driver don't use kernel space
to allocate skb buffers. Currently the external buffer can be from
guest virtio-net driver.

The idea is simple, just to pin the guest VM user space and then
let host NIC driver has the chance to directly DMA to it. 
The patches are based on vhost-net backend driver. We add a device
which provides proto_ops as sendmsg/recvmsg to vhost-net to
send/recv directly to/from the NIC driver. KVM guest who use the
vhost-net backend may bind any ethX interface in the host side to
get copyless data transfer thru guest virtio-net frontend.

patch 01-11:  	net core and kernel changes.
patch 12-14:  	new device as interface to mantpulate external buffers.
patch 15: 	for vhost-net.
patch 16:	An example on modifying NIC driver to using napi_gro_frags().
patch 17:	An example how to get guest buffers based on driver
		who using napi_gro_frags().

The guest virtio-net driver submits multiple requests thru vhost-net
backend driver to the kernel. And the requests are queued and then
completed after corresponding actions in h/w are done.

For read, user space buffers are dispensed to NIC driver for rx when
a page constructor API is invoked. Means NICs can allocate user buffers
from a page constructor. We add a hook in netif_receive_skb() function
to intercept the incoming packets, and notify the zero-copy device.

For write, the zero-copy deivce may allocates a new host skb and puts
payload on the skb_shinfo(skb)->frags, and copied the header to skb->data.
The request remains pending until the skb is transmitted by h/w.

We provide multiple submits and asynchronous notifiicaton to 
vhost-net too.

Our goal is to improve the bandwidth and reduce the CPU usage.
Exact performance data will be provided later.

What we have not done yet:
	Performance tuning

what we have done in v1:
	polish the RCU usage
	deal with write logging in asynchroush mode in vhost
	add notifier block for mp device
	rename page_ctor to mp_port in netdevice.h to make it looks generic
	add mp_dev_change_flags() for mp device to change NIC state
	add CONIFG_VHOST_MPASSTHRU to limit the usage when module is not load
	a small fix for missing dev_put when fail
	using dynamic minor instead of static minor number
	a __KERNEL__ protect to mp_get_sock()

what we have done in v2:
	
	remove most of the RCU usage, since the ctor pointer is only
	changed by BIND/UNBIND ioctl, and during that time, NIC will be
	stopped to get good cleanup(all outstanding requests are finished),
	so the ctor pointer cannot be raced into wrong situation.

	Remove the struct vhost_notifier with struct kiocb.
	Let vhost-net backend to alloc/free the kiocb and transfer them
	via sendmsg/recvmsg.

	use get_user_pages_fast() and set_page_dirty_lock() when read.

	Add some comments for netdev_mp_port_prep() and handle_mpassthru().

what we have done in v3:
	the async write logging is rewritten 
	a drafted synchronous write function for qemu live migration
	a limit for locked pages from get_user_pages_fast() to prevent Dos
	by using RLIMIT_MEMLOCK
	

what we have done in v4:
	add iocb completion callback from vhost-net to queue iocb in mp device
	replace vq->receiver by mp_sock_data_ready()
	remove stuff in mp device which access structures from vhost-net
	modify skb_reserve() to ignore host NIC driver reserved space
	rebase to the latest vhost tree
	split large patches into small pieces, especially for net core part.
	

what we have done in v5:
	address Arnd Bergmann's comments
		-remove IFF_MPASSTHRU_EXCL flag in mp device
		-Add CONFIG_COMPAT macro
		-remove mp_release ops
	move dev_is_mpassthru() as inline func
	fix a bug in memory relinquish
	Apply to current git (2.6.34-rc6) tree.

what we have done in v6:
	move create_iocb() out of page_dtor which may happen in interrupt context
	-This remove the potential issues which lock called in interrupt context
	make the cache used by mp, vhost as static, and created/destoryed during
	modules init/exit functions.
	-This makes multiple mp guest created at the same time.

what we have done in v7:
	some cleanup prepared to suppprt PS mode

what we have done in v8:
	discarding the modifications to point skb->data to guest buffer directly.
	Add code to modify driver to support napi_gro_frags() with Herbert's comments.
	To support PS mode.
	Add mergeable buffer support in mp device.
	Add GSO/GRO support in mp deice.
	Address comments from Eric Dumazet about cache line and rcu usage.

what we have done in v9:
	v8 patch is based on a fix in dev_gro_receive().
	But Herbert did not agree with the fix we have sent out.
	And he suggest another fix. v9 is modified to base on that fix.
	

what we have done in v10:
	Fix a partial csum error.
	Cleanup some unused fields with struct page_info{} in mp device.
	Modify kmem_cache_zalloc() to kmem_cache_alloc() based on Michael S. Thirkin.

what we have done in v11:
	Address comments from Michael S. Thirkin to add two new ioctls in mp device.
	But still need to revise.

what we have done in v12:
	Address most comments from Ben Hutchings, except the compat ioctls.
	As the comments are sparse, so do not make a split patch.
	Change struct mpassthru_port to struct mp_port, and struct page_ctor
	to struct page_pool.

what we have done in v13:
	Export functions to other drivers like macvtap, in case it want to reuse it to
	get zero-copy.
	Rebase on 2.6.36-rc7.

what we have done in v14:
	Address the comments from David Miller for bonding device issue.
	Currently, we treat it in two cases. One case is that bonding is created before
	zero-copy mode is enabled for a device. The code will check if all the slaves are
	capable of zero-copy. If yes, it will force all the slaves in zero-copy mode.
	If not, fails zero-copy. The other case is that zero-copy is enabled before bonding
	is created, just fail bonding.

what we have done in v15:
	Address comments from Eric Dumazet about how to clear destructor_arg field of shinfo.

what we have done in v16:
	Remove the modification to skb_release_data(), and don't touch the function now.
	Before we think it's simple to free the guest buffer in skb_release_data() when kernel
	wants to free the skb in case something is wrong. And now we think in RX zero-copy case,
	the skb will never tour into the stack, so we can only care if the driver wants to free
	the skb, and intercept the wrong skb there and then release the guest buffer. Thus we 
	can avoid to modify skb_release_data().

Performance:
	We have seen the performance data request from mailling-list.
	And we are now looking into this.

^ permalink raw reply

* Re: multi bpf filter will impact performance?
From: Eric Dumazet @ 2010-12-01  8:09 UTC (permalink / raw)
  To: Changli Gao; +Cc: Rui, netdev
In-Reply-To: <AANLkTinQ9c_C6LzNf5c3BbJXQTVKmbqf6KR9K23tGETw@mail.gmail.com>

Le mercredi 01 décembre 2010 à 15:59 +0800, Changli Gao a écrit :
> On Wed, Dec 1, 2010 at 3:47 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> > Le mercredi 01 décembre 2010 à 15:36 +0800, Changli Gao a écrit :
> >
> > Oh well, it seems you read over my neck, I was preparing a patch with
> > SKF_AD_RXHASH and SKF_AD_CPU
> >
> >
> 
> Nice to hear it. :)
> 
> There are too many filters: bpf, iptables and tc. Maybe an unified one
> such as nft is needed. Then the duplicate code would be reduced. Maybe
> it is just a good dream.
> 

You forgot the rxhash function as well, it would be nice to augment it
with custom code if necessary.

A dream would be to have a native compiler, and not interpret pseudo
code...




^ permalink raw reply

* Re: multi bpf filter will impact performance?
From: Changli Gao @ 2010-12-01  8:15 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Rui, netdev
In-Reply-To: <1291190956.2856.485.camel@edumazet-laptop>

On Wed, Dec 1, 2010 at 4:09 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>
> A dream would be to have a native compiler, and not interpret pseudo
> code...
>

FYI: FreeBSD's BPF implementation have JIT compilers in kernel on both
i386 and amd64.

-- 
Regards,
Changli Gao(xiaosuo@gmail.com)

^ permalink raw reply

* Re: IPV6 loopback bound socket succeeds connecting to remote host
From: Shan Wei @ 2010-12-01  8:18 UTC (permalink / raw)
  To: Albert Pretorius
  Cc: netdev, yoshfuji@linux-ipv6.org >> YOSHIFUJI Hideaki,
	David Miller, pekkas, jmorris
In-Reply-To: <328335.88387.qm@web29006.mail.ird.yahoo.com>

Albert Pretorius wrote, at 11/29/2010 06:55 PM:
> Hi
> I found a problem with ipv6 when a UDP socket is bound to loopback (::1) and connecting to a remote address. The same applies to TCP.
> Any data sent ends up on the remote host with a source address of loopback. The expected result of the connect should be EINVAL just like it is for ipv4.
> Here is a possible patch that fixes this problem below. I tested it on 2.6.37-rc3 using a tool I put on http://www.gitorious.org/bindconnect

Indeed, there is  an guide in RFC4291 for us to use IPv6 loopback address.

See RFC4291 2.5.3 section:
   The loopback address must not be used as the source address in IPv6
   packets that are sent outside of a single node.  An IPv6 packet with
   a destination address of loopback must never be sent outside of a
   single node and must never be forwarded by an IPv6 router.  A packet
   received on an interface with a destination address of loopback must
   be dropped.

I think it make nonsense to translate data between loopback device and
other e.g. eth0 device in same machine. With your patch, also can't establish
a tcp connection from loopback device to other device in same host.  

=====
[PATCH] ipv6: forbid to send ipv6 packet from loopback to other device in same host

According to 2.5.3 section of RFC4291, commit f630e43 dropped the received packet with
loopback as destination address. Now forbid to send packet from loopback to other
device. Original patch is provided by Albert Pretorius.


Reported-by: Albert Pretorius <albertpretorius@yahoo.co.uk>
Signed-off-by: Shan Wei <shanwei@cn.fujitsu.com>
---
 net/ipv6/ip6_output.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 99157b4..6b6cf84 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -927,6 +927,7 @@ static int ip6_dst_lookup_tail(struct sock *sk,
 {
 	int err;
 	struct net *net = sock_net(sk);
+	struct net_device *dev_out;
 
 	if (*dst == NULL)
 		*dst = ip6_route_output(net, sk, fl);
@@ -934,6 +935,13 @@ static int ip6_dst_lookup_tail(struct sock *sk,
 	if ((err = (*dst)->error))
 		goto out_err_release;
 
+	dev_out = ip6_dst_idev(*dst)->dev;
+	if (dev_out && ipv6_addr_loopback(&fl->fl6_src) &&
+	    !(dev_out->flags & IFF_LOOPBACK)) {
+		err = -EINVAL;
+		goto out_err_release;
+	}
+
 	if (ipv6_addr_any(&fl->fl6_src)) {
 		err = ipv6_dev_get_saddr(net, ip6_dst_idev(*dst)->dev,
 					 &fl->fl6_dst,
-- 
1.6.3.3


^ permalink raw reply related

* Re: [Patch] bonding: clean up netpoll code
From: Cong Wang @ 2010-12-01  8:26 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: linux-kernel, Jiri Pirko, Neil Horman, netdev, David S. Miller,
	Eric W. Biederman, Herbert Xu, bonding-devel, Jay Vosburgh,
	Stephen Hemminger
In-Reply-To: <1291190612.2856.481.camel@edumazet-laptop>

On 12/01/10 16:03, Eric Dumazet wrote:
> Le mercredi 01 décembre 2010 à 02:45 -0500, Amerigo Wang a écrit :
>> Against net-next-2.6.
>>
>> This patch unifies the netpoll code in bonding with netpoll code in bridge,
>> thanks to Herbert that code is much cleaner now.
>>
>> It also removes the flag IFF_IN_NETPOLL, we don't need it any more since
>> we have netpoll_tx_running() now.
>>
>> It passes my basic testings.
>
> Sorry this NETPOLL patch is frightening...
>
> Could you split it in several parts ?
>
> The removal of IFF_IN_NETPOLL deserves a patch on its own, its not a
> cleanup at all, if you ask me.
>

Is this necessary?
It is just replacing checking IFF_IN_NETPOLL with netpoll_tx_running(),
you might need to take a look at the bridge code.

^ permalink raw reply

* Re: multi bpf filter will impact performance?
From: Eric Dumazet @ 2010-12-01  8:42 UTC (permalink / raw)
  To: Changli Gao; +Cc: Rui, netdev
In-Reply-To: <AANLkTin6d=t6U28A-r=FznqE+5QuGXwg1tStOw-JXabg@mail.gmail.com>

Le mercredi 01 décembre 2010 à 16:15 +0800, Changli Gao a écrit :
> On Wed, Dec 1, 2010 at 4:09 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> >
> > A dream would be to have a native compiler, and not interpret pseudo
> > code...
> >
> 
> FYI: FreeBSD's BPF implementation have JIT compilers in kernel on both
> i386 and amd64.
> 


IMHO, a better pcap optimizer would be the first step.

If you take a look at their generated code, its not a real win over the
code we currently have.


Really.




^ permalink raw reply

* Re: [Patch] bonding: clean up netpoll code
From: Herbert Xu @ 2010-12-01  9:06 UTC (permalink / raw)
  To: Cong Wang
  Cc: Eric Dumazet, linux-kernel, Jiri Pirko, Neil Horman, netdev,
	David S. Miller, Eric W. Biederman, bonding-devel, Jay Vosburgh,
	Stephen Hemminger
In-Reply-To: <4CF606C7.6020606@redhat.com>

On Wed, Dec 01, 2010 at 04:26:47PM +0800, Cong Wang wrote:
>
> Is this necessary?
> It is just replacing checking IFF_IN_NETPOLL with netpoll_tx_running(),
> you might need to take a look at the bridge code.

I agree with Eric.  The patch does look pretty scary right now.

Each patch should do one thing and one thing only.

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

* Re: [PATCH v16 11/17]Add a hook to intercept external buffers from NIC driver.
From: Changli Gao @ 2010-12-01  9:38 UTC (permalink / raw)
  To: xiaohui.xin
  Cc: netdev, kvm, linux-kernel, mst, mingo, davem, herbert, jdike,
	Eric Dumazet
In-Reply-To: <c1b20adfd68fc241611845c0ef42fe8fa91ed981.1291187695.git.xiaohui.xin@intel.com>

On Wed, Dec 1, 2010 at 4:08 PM,  <xiaohui.xin@intel.com> wrote:
> From: Xin Xiaohui <xiaohui.xin@intel.com>
> @@ -2891,6 +2925,11 @@ static int __netif_receive_skb(struct sk_buff *skb)
>  ncls:
>  #endif
>
> +       /* To intercept mediate passthru(zero-copy) packets here */
> +       skb = handle_mpassthru(skb, &pt_prev, &ret, orig_dev);
> +       if (!skb)
> +               goto out;
> +
>        /* Handle special case of bridge or macvlan */

I think it won't work if the skbs is captured by the previous ptype.
We need to trace the skb pages(skb_shared_info.frags[*].page), but
currently, there isn't a easy way to do that. skb pages are treated as
normal pages, and anyone can get it freely. And it is the problem in
the way to fix the potential data corruption bug.

Eric thinks af_packets(mmap) isn't worth fixing. But if this patch
serial has the same problem. It will be worth.

My idea is adding a new function dtor pointer  and some other args
pointers to the struct skb_shared_info. If skb_shared_info.dtor
exists, the pages in skb_shared_info.frags are private to this
skb->head. Anyone who wants to get these pages, should copy them
instead.

-- 
Regards,
Changli Gao(xiaosuo@gmail.com)

^ permalink raw reply

* RE: [PATCH] net/r8169: Remove the firmware of RTL8111D
From: hayeswang @ 2010-12-01  9:54 UTC (permalink / raw)
  To: 'Francois Romieu'; +Cc: netdev, linux-kernel, 'Ben Hutchings'
In-Reply-To: <20101201080732.GA3234@electric-eye.fr.zoreil.com>

[-- Attachment #1: Type: text/plain, Size: 1930 bytes --]

Hi Romieu,

the rtl8168d_3_hw_phy_config is RTL8111DP which is different from RTL8111D(L).
I want to deal with RTL8111D first.

The attatched file is the linux-firmware patch.

I would think the situation for the failure of request_firmware. However, maybe
it is fine to go along.

Thanks for your suggestion and reply.
 
Best Regards,
Hayes


> -----Original Message-----
> From: Francois Romieu [mailto:romieu@fr.zoreil.com] 
> Sent: Wednesday, December 01, 2010 4:08 PM
> To: Hayeswang
> Cc: netdev@vger.kernel.org; linux-kernel@vger.kernel.org; Ben 
> Hutchings
> Subject: Re: [PATCH] net/r8169: Remove the firmware of RTL8111D
> 
> Hayes Wang <hayeswang@realtek.com> :
> > Remove the firmware of RTL8111D from the kernel.
> > The binary file of firmware would be moved to 
> linux-firmware repository.
> 
> The driver can not simply go along when request_firmware 
> fails. Though Ben's
> code did not take care of it, the driver should imho 
> propagate some return
> code. Ben ?
> 
> There is no change in rtl8168d_3_hw_phy_config : could you 
> add a comment
> so that people know it is different ?
> 
> Could you Cc: the linux-firmware patch as well ?
> 
> Minor nit: please keep the code free of capitalized hex data.
> 
> > diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
> > index 7d33ef4..cad1ba8 100644
> > --- a/drivers/net/r8169.c
> > +++ b/drivers/net/r8169.c
> [...]
> > @@ -1383,6 +1384,28 @@ static void rtl_phy_write(void 
> __iomem *ioaddr, const struct phy_reg *regs, int
> >  	}
> >  }
> >  
> > +static void rtl_phy_write_fw(void __iomem *ioaddr, const 
> struct firmware *fw)
> > +{
> [...]
> > +		default:
> > +			printk(KERN_WARNING "%s: Unknown action\n",
> > +				__FUNCTION__);
> 
> A bit old school. It gives no information about the device.
> Use netif_{err/info} or such ?
> 
> Thanks.
> 
> -- 
> Ueimor
> 
> 
> ------Please consider the environment before printing this e-mail. 
> 
> 
> 

[-- Attachment #2: 0001-rtl_nic-Add-firmware-for-RTL8111D-L.patch --]
[-- Type: application/octet-stream, Size: 3982 bytes --]

>From 706b34566b9318ae50b9b931178ee6b66b05080a Mon Sep 17 00:00:00 2001
From: Hayes Wang <hayeswang@realtek.com>
Date: Wed, 1 Dec 2010 10:21:47 +0800
Subject: [PATCH] rtl_nic: Add firmware for RTL8111D(L)

Add firmware for r8169 of kernel for RTL8111D
	rtl_nic/rtl8168d-1.fw
	rtl_nic/rtl8168d-2.fw

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 WHENCE                |   14 ++++++++++++++
 rtl_nic/rtl8168d-1.fw |  Bin 0 -> 1492 bytes
 rtl_nic/rtl8168d-2.fw |  Bin 0 -> 1324 bytes
 3 files changed, 14 insertions(+), 0 deletions(-)
 create mode 100644 rtl_nic/rtl8168d-1.fw
 create mode 100644 rtl_nic/rtl8168d-2.fw

diff --git a/WHENCE b/WHENCE
index 907fe68..e2aca61 100644
--- a/WHENCE
+++ b/WHENCE
@@ -1451,3 +1451,17 @@ Licence: Redistributable. See LICENCE.rtlwifi_firmware for details.
 
 --------------------------------------------------------------------------
 
+Driver: r8169 - RealTek 8169/8168/8101 ethernet driver.
+
+File: rtl_nic/rtl8168d-1.fw
+File: rtl_nic/rtl8168d-2.fw
+
+Licence:
+ * Copyright (c) 2010, Realtek Semiconductor Corporation 
+ *
+ * Permission is hereby granted for the distribution of this firmware
+ * data in hexadecimal or equivalent format, provided this copyright
+ * notice is accompanying it.
+
+--------------------------------------------------------------------------
+
diff --git a/rtl_nic/rtl8168d-1.fw b/rtl_nic/rtl8168d-1.fw
new file mode 100644
index 0000000000000000000000000000000000000000..99e002de1fb965d53822bc9ea0f5a8ca12d27f62
GIT binary patch
literal 1492
zcmb7^&2LO$6vppN=N_%1<0Fx(AYx^uEX1yhrar4ANXv!=@gJx}lSjwKS7IZ?qOFKT
zM$#s%SeTtHN*bc#8Z8OQj1|)lQ@=C!PBeBFH_v<C^YK3KbIyIkV55F6gi>G%6l$ho
zD$klqeWq`$OYDCKBk%%P`DE%FAg0B%D`gr=vo_XQ({Lm4TmQ);rk>YJ-cSdz<mS6f
zg=W)@LDS%bDSg}2Lu}J1cEL1(J%TUg^?OX!o2L2SoFAHIXTTDCza{t`ESf%FFb%+Q
z<$cqtm8OnyQ>WMNG_9r92zK7>d~COHRwuFU?`EC%HNM@>VT`-1HXY2x8gx6t`#^#{
z$^PL4_c<<@_Ja|)4a}icZ@X!#YP#auP2;<2+Mf9Oc9@FP^x9jNnSLCH_XgsoOw-p)
z*U51n5j_07DKvJ>MW+6P=uJ<erSV>Ng!AF=d?R#p4Es%YhW^G6W$;nMeGT|p7W>E<
z4NYV4s9ZE%<lM1)rb*UyE%uP-^RO56dGNbCC&yGTeIKSLFHL%7I<qn92|e=psc^SV
zezz~&E!j)Irmv6VxH7#vv7H_&?qLJm7MPdiXt|!+>yFab)6C0VG$YTs<UX6)_L?3Z
zV@8<0FJNu|t0~KVoks?3ickLLl<^g*<vpv_*iY}h#)`N`ZJ!!N_PsYbI7bKKbwDlG
z$aV2PWV=E7H3|xSeI2o`Yuvn8WBesP_eIS0|IC4(^=X@_o!rz}G~=A<E2gVxyOVj%
zmFOumQHx8srrJyy&cB;CJxF3Q9z$%<gKoY@-G0`?4RBi%a~o$4COS+<(0mY{<7=@;
z$axyuRqXn|SaDt_O{d_IuJcOlnr{#Dg0F=hroI2pJK6JD@%n`mrbFDTt88kWG`;*l
zY>Ii{pLKt9&UBI*{`T~qV&-@UYW6fduxHS8jyJ3D+|)r_?iv63A#|cf+Y-}@%ce&D
z{r9{Rk6M|lIn(bd^~hVyv9ZoS;r9#9i}_~enPGaH4osWT(eWd8iW&WY?KsQ%W$G8s
z6T`aoEu7z>?<Mw{OwasI{szI--@9Afxk_G0?FDpA!7Bj${%>=k4h!u;e+%D$0d{s%
VTES$40^aVxniVE*_&j`k?+=A!Np1iD

literal 0
HcmV?d00001

diff --git a/rtl_nic/rtl8168d-2.fw b/rtl_nic/rtl8168d-2.fw
new file mode 100644
index 0000000000000000000000000000000000000000..7022ab0af4753c529a1646bc921d9d1889767fde
GIT binary patch
literal 1324
zcmb7^OGs2<6vyv8?#a}eDFQJ=C8D+3qOA)l&Bs_&Ot#U5;ihF^kZ^R`qy_DQ7UQ@W
ziU~%jRV@lyxXlNMk<wL11BJ0w`JR5?eAl#PtMi@r|NPIn*L7<2SHV?vL>+Z?Yg078
zExKkTwsqtZ@)2@#Su{N$dg_$u^l8!AM$x7w(ZL}41bRv|ld*ahJsq+BEdF%6^_lnh
zRngCbqKP~`JFJZ0H+rPax5s>W-O9o>U$!DW(ZxE^`h@6y99%ikm0{5lFcy6cqL=VR
z?w~J;mQ%ayf@t+m(Hyv+npsxB@yy3Ty{PF&9S_+-uG24CI%?~su%)BC!51)iiSI`y
zUE*Kb_%QL&<Pl#8U&Q(X_*{JDS-2Ue?<>(8%wK$u9O0tb_HbHkov4`|OmXCBKy-3V
zbjlH}QFe0A?#S$<Yn|DcX|>k3G20BbcW}M5Z+F+QA*y%n4wLL~0DOf4wNHrNIw#tD
zR&<QL&OE0loGpW;1s-l!iI%)UlAl-={o&iE;KSfZf#ZGn-<)0(Yih8wR=>u{%#j+t
z-NdZ2n>Jz$rzzg$j^)LJmv-zq`WP98yBz(@`!D|?I4(QnKWzBViw4=v|J;Gc9n_h+
zi=ut?^nvSP_%t_?1xNm}?cvd{h?Tf1uqKJiFne~4nAbKYj~=5|mN`6lGw%@lKVxnQ
zY%bUur{R1SoHs=$2ALcEgVD(``W`!TcgY7sx52Rpt{!j&eH~mLdb96~b1&5q>o3~y
zPhvCmN{8tCNpz!AbpDFyLM1mmDLO>0V5#Uu{F@%%Q@3aj_4eZE+}w(<hrzME1+E?J
z)cM#b+R03Tl<2X5=o9W^`V0Sw64A<UqC0Q-Cb_Hdp2dHFu@5{sVh->b%(>r(`Yw7q
z+&Q)I2sY<DI<oK`oj!#H`XhJvH$CLO43;@!zB12aFdrXfCTz3!MIQ`-kKBzIc`rnF
s;j_ZExGJa-aHx-eF5&XeBL^8HCt4d+XFjA3|3pX1)b;<3yC$CZAI_u&^8f$<

literal 0
HcmV?d00001

-- 
1.7.3.2


^ permalink raw reply related

* Re: BUG - routes not correctly deleted when address is deleted
From: Julian Anastasov @ 2010-12-01 10:08 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Miller, netdev
In-Reply-To: <20101130165539.40ce02c1@nehalam>


 	Hello,

On Tue, 30 Nov 2010, Stephen Hemminger wrote:

> If multiple addresses are assigned to an interface, and
> a route is created that uses that address.  The route is not
> deleted when the address is deleted.  Linux does cleanup properly
> when the last address is deleted; it seems the FIB lacks the callback
> to cleanup routes referencing an address.
>
> Simple example:
>
> # modprobe dummy
> # ip li set dev dummy0 up
> # ip addr add 192.168.74.160/24 dev dummy0
> # ip addr add 192.168.18.11/24 dev dummy0
> # ip ro add 74.11.49.0/24 via 192.168.74.160

 	Such routes look as old way to create direct
routes over some device, used by "route" tool.
Device is inherited from the local IP used as gateway.
Such local gateways IPs are not used, see rt_set_nexthop()
where nh_scope is checked. FIB removes routes only when
the deleted IP is a prefsrc for this route, so may be
it is a good idea to use prefsrc.

> # ip addr del 192.168.74.160/24 dev dummy0
> # ip ro show dev dummy0
> 74.11.49.0/24 via 192.168.74.160
> 192.168.18.0/24  proto kernel  scope link  src 192.168.18.11
>
> Before I go off and either brute force it (add another call back
> into fib_hash and fib_trie), is there a better way?

 	Adding prefsrc is recommended. For me, it is not fatal
such routes to stay because nh_gw is not used. It is a
way to say at configuration time:

ip ro add 74.11.49.0/24 dev eth0

 	If you need such route to depend on the lifetime
of some local IP then you need to specify prefsrc.

 	If you go ahead with changes may be you should call 
fib_sync_down_dev from fib_del_ifaddr by providing the IP
as new argument. While fib_sync_down_addr is called when this
IP is removed from the last device where it was configured,
now for nh_gw fib_sync_down_dev should be called for every
fib_del_ifaddr call. For me, it is a complication, not sure
what others think.

Regards

--
Julian Anastasov <ja@ssi.bg>

^ permalink raw reply

* Re: 2.6.35 -> 2.6.36 panic when vlan and promisc with tg3
From: Michael Leun @ 2010-12-01 10:17 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Ben Greear, linux-kernel, netdev
In-Reply-To: <1291108809.2904.3.camel@edumazet-laptop>

On Tue, 30 Nov 2010 10:20:09 +0100
Eric Dumazet <eric.dumazet@gmail.com> wrote:

> Le mardi 30 novembre 2010 à 09:59 +0100, Michael Leun a écrit :
> > On Mon, 29 Nov 2010 16:19:06 -0800
> > Ben Greear <greearb@candelatech.com> wrote:
> > 
> > > On 11/29/2010 11:17 AM, Michael Leun wrote:
> > > > UG: unable to handle kernel paging request at 01cc921c
> > > > IP: [<c034bfce>] vlan_hwaccel_do_receive+0x59/0xd0
> > > > *pdpt = 0000000036a2a001 *pde = 0000000000000000
> > > > Oops: 0002 [#1] SMP
> > > > last sysfs
> > > >
> > > > Then machine dead.
> > > >
> > > > In 2.6.35.x this did not happen (but vlans broken - cannot see
> > > > vlan tags with tcpdump),
> > > 
> > > Try this patch:
> > > 
> > > http://permalink.gmane.org/gmane.linux.network/176566
> > > 
> > > It looks like this hasn't made it into stable yet?
> > 
> > > > To reproduce:
> > > >
> > > > ip link set eth0 up
> > > > vconfig add eth0 2
> > > > ip link set eth0 promisc on
> > 
> > It makes it better - it does not crash anymore on this commands -
> > but if you add an "tcpdump -i eth0 -n" at the end it does. So,
> > unfortunately no real solution.
> > 
> > I guess, "dropping packet no one is interested in" (as noted in the
> > patch) does not work very well if tcpdump is actually interested?
> > 
> 
> Could you try with following patch instead, for net/core/dev.c 
> 
> (and keep the net/8021q/vlan_core.c part)
> 
> --- net/core/dev.c.orig
> +++ net/core/dev.c
> @@ -2891,6 +2891,9 @@
>  ncls:
>  #endif
>  
> +	if (unlikely(vlan_tx_tag_present(skb)))
> +		goto bypass;
> +
>  	/* Handle special case of bridge or macvlan */
>  	rx_handler = rcu_dereference(skb->dev->rx_handler);
>  	if (rx_handler) {
> @@ -2927,6 +2930,7 @@
>  		}
>  	}
>  
> +bypass:
>  	if (pt_prev) {
>  		ret = pt_prev->func(skb, skb->dev, pt_prev,
> orig_dev); } else {
> 
> 

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!).

-- 
MfG,

Michael Leun


^ permalink raw reply

* Re: BUG in skb_dequeue (skb->next is NULL) (was: Re: Kernel crash with 2.6.36)
From: Eric Dumazet @ 2010-12-01 10:28 UTC (permalink / raw)
  To: Simon Schubert; +Cc: linux-kernel, netdev
In-Reply-To: <loom.20101201T095252-592@post.gmane.org>

Le mercredi 01 décembre 2010 à 09:02 +0000, Simon Schubert a écrit :
> Frédéric L. W. Meunier <2 <at> pervalidus.net> writes:

CC netdev

> 
> > Nov  7 16:21:23 pervalidus kernel: BUG: unable to handle kernel NULL pointer 
> dereference at (null)
> 
> I can confirm the bug reported by Frederic.  The culprit is at:
> 
>         next->prev = prev;
> 
> in __skb_unlink().
> 
> Something must be putting NULL pointers in the skb list.
> 
> Let me know how I can be of further help.
> 
> 
> BUG: unable to handle kernel NULL pointer dereference at (null)
> IP: [<ffffffff81459069>] skb_dequeue+0x59/0x90
> PGD 208379067 PUD 20a523067 PMD 0 
> Oops: 0002 [#1] SMP 
> last sysfs file: /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq
> CPU 1 
> Modules linked in: binfmt_misc kvm_intel kvm ipt_MASQUERADE iptable_nat nf_nat 
> xfrm_user nf_conntrack_ipv4 xfrm4_tunnel tunnel4 nf_conntrack ipcomp xfrm_ipcomp 
> esp4 ah4 nf_defrag_ipv4 xt_TCPMSS xt_tcpmss xt_tcpudp iptable_mangle deflate 
> ip_tables zlib_deflate ctr x_tables twofish_generic twofish_x86_64 
> twofish_common camellia serpent blowfish cast5 des_generic xcbc rmd160 
> sha512_generic sha1_generic crypto_null af_key pppoe pppox xfs exportfs 
> snd_hda_codec_via snd_hda_intel snd_hda_codec snd_hwdep snd_pcm_oss 
> snd_mixer_oss snd_pcm snd_seq_dummy snd_seq_oss snd_seq_midi snd_rawmidi 
> snd_seq_midi_event snd_seq snd_timer ftdi_sio snd_seq_device usbserial hwmon_vid 
> coretemp snd lp tpm_tis ppdev tpm parport_pc asus_atk0110 tpm_bios parport 
> soundcore snd_page_alloc sha256_generic cryptd aes_x86_64 aes_generic dm_crypt 
> raid10 raid1 raid0 multipath linear raid456 async_pq async_xor xor async_memcpy 
> async_raid6_recov raid6_pq async_tx fbcon tileblit font bitblit softcursor usb
> 
> Pid: 2229, comm: pulseaudio Not tainted 2.6.36 #10 P5Q-VM DO/System Product Name
> RIP: 0010:[<ffffffff81459069>]  [<ffffffff81459069>] skb_dequeue+0x59/0x90
> RSP: 0018:ffff880221927a78  EFLAGS: 00010097
> RAX: 0000000000000282 RBX: ffff88017a6d5e14 RCX: ffff88022236d200
> RDX: 0000000000000000 RSI: 0000000000000282 RDI: ffff88017a6d5e14
> RBP: ffff880221927a98 R08: 0000000000000000 R09: 0000000000000000
> R10: 0000000000000000 R11: 0000000000000293 R12: ffff88022236d200
> R13: ffff88017a6d5e00 R14: 0000000000000000 R15: 0000000000000000
> FS:  00007fedd4d9f740(0000) GS:ffff880001e80000(0000) knlGS:0000000000000000
> CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
> CR2: 0000000000000000 CR3: 000000020837a000 CR4: 00000000000006e0
> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> Process pulseaudio (pid: 2229, threadinfo ffff880221926000, task 
> ffff8802210096d0)
> Stack:
>  ffff88022236d200 ffff88022236d228 ffff88022236d200 ffff880221927f18
> <0> ffff880221927be8 ffffffff814ef0fa ffff880221927e4c ffff880221927eb4
> <0> 0000000000000040 ffff8802210096d0 ffff8802210096d0 ffff88017a6d5ea4
> Call Trace:
>  [<ffffffff814ef0fa>] unix_stream_recvmsg+0x1aa/0x790
>  [<ffffffff8145124d>] sock_recvmsg+0xfd/0x130
>  [<ffffffff81155fd0>] ? pollwake+0x0/0x60
>  [<ffffffff81452b54>] __sys_recvmsg+0x144/0x2e0
>  [<ffffffff81155fd0>] ? pollwake+0x0/0x60
>  [<ffffffff8104d88a>] ? finish_task_switch+0x4a/0xd0
>  [<ffffffff8154fa91>] ? schedule+0x411/0xa50
>  [<ffffffff81452f99>] sys_recvmsg+0x49/0x80
>  [<ffffffff8100b0b2>] system_call_fastpath+0x16/0x1b
> Code: e5 74 4f 4d 85 e4 74 26 41 83 6d 10 01 49 8b 0c 24 49 8b 54 24 08 49 c7 04 
> 24 00 00 00 00 49 c7 44 24 08 00 00 00 00 48 89 51 08 <48> 89 0a 48 89 c6 48 89 
> df e8 39 93 0f 00 4c 89 e0 48 8b 5d e8 
> RIP  [<ffffffff81459069>] skb_dequeue+0x59/0x90
>  RSP <ffff880221927a78>
> CR2: 0000000000000000
> ---[ end trace d4be3de9fdd70935 ]---
> 
> cheers
>   simon
> 
> 

Is it reproductible ?

On previous kernel (say 2.6.35) you never hit this bug ?

^ permalink raw reply

* Re: BUG in skb_dequeue (skb->next is NULL)
From: Simon Schubert @ 2010-12-01 10:34 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: linux-kernel, netdev
In-Reply-To: <1291199299.2856.499.camel@edumazet-laptop>

[-- Attachment #1: Type: text/plain, Size: 991 bytes --]

On 12/01/2010 11:28 AM, Eric Dumazet wrote:
> Le mercredi 01 décembre 2010 à 09:02 +0000, Simon Schubert a écrit :
>> Frédéric L. W. Meunier <2 <at> pervalidus.net> writes:
> 
> CC netdev
>> RIP: 0010:[<ffffffff81459069>]  [<ffffffff81459069>] skb_dequeue+0x59/0x90
>> Call Trace:
>>  [<ffffffff814ef0fa>] unix_stream_recvmsg+0x1aa/0x790
>>  [<ffffffff8145124d>] sock_recvmsg+0xfd/0x130
>>  [<ffffffff81155fd0>] ? pollwake+0x0/0x60
>>  [<ffffffff81452b54>] __sys_recvmsg+0x144/0x2e0
>>  [<ffffffff81155fd0>] ? pollwake+0x0/0x60
>>  [<ffffffff8104d88a>] ? finish_task_switch+0x4a/0xd0
>>  [<ffffffff8154fa91>] ? schedule+0x411/0xa50
>>  [<ffffffff81452f99>] sys_recvmsg+0x49/0x80
>>  [<ffffffff8100b0b2>] system_call_fastpath+0x16/0x1b
> 
> Is it reproductible ?

I can't trigger it on purpose, but it happened two nights in a row (I
don't have the previous backtrace though)

> On previous kernel (say 2.6.35) you never hit this bug ?

No.

cheers
  simon


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 900 bytes --]

^ permalink raw reply

* [PATCH 2.6.36] vlan: Avoid hwaccel vlan packets when vid not used
From: Eric Dumazet @ 2010-12-01 10:55 UTC (permalink / raw)
  To: Michael Leun, David Miller
  Cc: Ben Greear, linux-kernel, netdev, Jesse Gross, stable
In-Reply-To: <20101201111716.424fb771@xenia.leun.net>

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!).
> 

Thanks Michael !

Here is the revised patch again then for stable team, via David Miller
agreement.


[PATCH v2 2.6.36] vlan: Avoid hwaccel vlan packets when vid not used.

Normally hardware accelerated vlan packets are quickly dropped if
there is no corresponding vlan device configured.  The one exception
is promiscuous mode, where we allow all of these packets through so
they can be picked up by tcpdump.  However, this behavior causes a
crash if we actually try to receive these packets.  This fixes that
crash by ignoring packets with vids not corresponding to a configured
device in the vlan hwaccel routines and then dropping them before they
get to consumers in the network stack.

Reported-by: Ben Greear <greearb@candelatech.com>
Signed-off-by: Jesse Gross <jesse@nicira.com>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Tested-by: Michael Leun <lkml20101129@newton.leun.net>
---
v2: survives to tcpdump :)

 net/core/dev.c        |   10 ++++++++++
 net/8021q/vlan_core.c |    3 +++
 2 files changed, 13 insertions(+)

--- linux-2.6.36/net/core/dev.c.orig
+++ linux-2.6.36/net/core/dev.c
@@ -2891,6 +2891,15 @@
 ncls:
 #endif
 
+	/* If we got this far with a hardware accelerated VLAN tag, it means
+	 * that we were put in promiscuous mode but nobody is interested in
+	 * this vid. Drop the packet now to prevent it from getting propagated
+	 * to other parts of the stack that won't know how to deal with packets
+	 * tagged in this manner.
+	 */
+	if (unlikely(vlan_tx_tag_present(skb)))
+		goto bypass;
+
 	/* Handle special case of bridge or macvlan */
 	rx_handler = rcu_dereference(skb->dev->rx_handler);
 	if (rx_handler) {
@@ -2927,6 +2936,7 @@
 		}
 	}
 
+bypass:
 	if (pt_prev) {
 		ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
 	} else {
--- linux-2.6.36/net/8021q/vlan_core.c.orig
+++ linux-2.6.36/net/8021q/vlan_core.c
@@ -43,6 +43,9 @@
 	struct net_device *dev = skb->dev;
 	struct vlan_rx_stats     *rx_stats;
 
+	if (unlikely(!is_vlan_dev(dev)))
+		return 0;
+
 	skb->dev = vlan_dev_info(dev)->real_dev;
 	netif_nit_deliver(skb);
 

^ permalink raw reply

* [PATCH net-next-2.6 1/3] be2net: Fix be_dev_family_check() return value check
From: Sathya Perla @ 2010-12-01 11:02 UTC (permalink / raw)
  To: netdev

Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
 drivers/net/benet/be_main.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 102567e..ca4bf9b 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -2899,7 +2899,7 @@ static int __devinit be_probe(struct pci_dev *pdev,
 	pci_set_drvdata(pdev, adapter);
 
 	status = be_dev_family_check(adapter);
-	if (!status)
+	if (status)
 		goto free_netdev;
 
 	adapter->netdev = netdev;
-- 
1.6.5.2


^ permalink raw reply related

* [PATCH net-next-2.6 2/3] be2net: FW init cmd fix for lancer
From: Sathya Perla @ 2010-12-01 11:03 UTC (permalink / raw)
  To: netdev

Lancer can use the same pattern as BE to indicate a driver load
to the FW.

Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar@emulex.com>
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
 drivers/net/benet/be_cmds.c |   27 ++++++++-------------------
 1 files changed, 8 insertions(+), 19 deletions(-)

diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index 3865b2b..31c5ddc 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -470,25 +470,14 @@ int be_cmd_fw_init(struct be_adapter *adapter)
 	spin_lock(&adapter->mbox_lock);
 
 	wrb = (u8 *)wrb_from_mbox(adapter);
-	if (lancer_chip(adapter)) {
-		*wrb++ = 0xFF;
-		*wrb++ = 0x34;
-		*wrb++ = 0x12;
-		*wrb++ = 0xFF;
-		*wrb++ = 0xFF;
-		*wrb++ = 0x78;
-		*wrb++ = 0x56;
-		*wrb = 0xFF;
-	} else {
-		*wrb++ = 0xFF;
-		*wrb++ = 0x12;
-		*wrb++ = 0x34;
-		*wrb++ = 0xFF;
-		*wrb++ = 0xFF;
-		*wrb++ = 0x56;
-		*wrb++ = 0x78;
-		*wrb = 0xFF;
-	}
+	*wrb++ = 0xFF;
+	*wrb++ = 0x12;
+	*wrb++ = 0x34;
+	*wrb++ = 0xFF;
+	*wrb++ = 0xFF;
+	*wrb++ = 0x56;
+	*wrb++ = 0x78;
+	*wrb = 0xFF;
 
 	status = be_mbox_notify_wait(adapter);
 
-- 
1.6.5.2


^ permalink raw reply related

* [PATCH net-next-2.6 3/3] be2net: Handle out of buffer completions for lancer
From: Sathya Perla @ 2010-12-01 11:04 UTC (permalink / raw)
  To: netdev

If Lancer chip does not have posted RX buffers, it posts an RX completion entry
with the same frag_index as the last valid completion. The Error bit is also
set. In BE, a flush completion is indicated with a zero value for num_rcvd in
the completion.
Such completions don't carry any data and are not processed.
This patch refactors code to handle both cases with the same code.

Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar@emulex.com>
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
 drivers/net/benet/be.h      |    4 ++-
 drivers/net/benet/be_main.c |   55 +++++++++++++++++++++++++++---------------
 2 files changed, 38 insertions(+), 21 deletions(-)

diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index b61a1df..9cab323 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -220,7 +220,9 @@ struct be_rx_obj {
 	struct be_rx_stats stats;
 	u8 rss_id;
 	bool rx_post_starved;	/* Zero rx frags have been posted to BE */
-	u32 cache_line_barrier[16];
+	u16 last_frag_index;
+	u16 rsvd;
+	u32 cache_line_barrier[15];
 };
 
 struct be_vf_cfg {
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index ca4bf9b..114a2d4 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -911,11 +911,17 @@ static void be_rx_compl_discard(struct be_adapter *adapter,
 	rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp);
 	num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
 
-	for (i = 0; i < num_rcvd; i++) {
-		page_info = get_rx_page_info(adapter, rxo, rxq_idx);
-		put_page(page_info->page);
-		memset(page_info, 0, sizeof(*page_info));
-		index_inc(&rxq_idx, rxq->len);
+	 /* Skip out-of-buffer compl(lancer) or flush compl(BE) */
+	if (likely(rxq_idx != rxo->last_frag_index && num_rcvd != 0)) {
+
+		rxo->last_frag_index = rxq_idx;
+
+		for (i = 0; i < num_rcvd; i++) {
+			page_info = get_rx_page_info(adapter, rxo, rxq_idx);
+			put_page(page_info->page);
+			memset(page_info, 0, sizeof(*page_info));
+			index_inc(&rxq_idx, rxq->len);
+		}
 	}
 }
 
@@ -1016,9 +1022,6 @@ static void be_rx_compl_process(struct be_adapter *adapter,
 	u8 vtm;
 
 	num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
-	/* Is it a flush compl that has no data */
-	if (unlikely(num_rcvd == 0))
-		return;
 
 	skb = netdev_alloc_skb_ip_align(adapter->netdev, BE_HDR_LEN);
 	if (unlikely(!skb)) {
@@ -1075,10 +1078,6 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter,
 	u8 pkt_type;
 
 	num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
-	/* Is it a flush compl that has no data */
-	if (unlikely(num_rcvd == 0))
-		return;
-
 	pkt_size = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp);
 	vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
 	rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp);
@@ -1349,7 +1348,7 @@ static void be_rx_q_clean(struct be_adapter *adapter, struct be_rx_obj *rxo)
 	while ((rxcp = be_rx_compl_get(rxo)) != NULL) {
 		be_rx_compl_discard(adapter, rxo, rxcp);
 		be_rx_compl_reset(rxcp);
-		be_cq_notify(adapter, rx_cq->id, true, 1);
+		be_cq_notify(adapter, rx_cq->id, false, 1);
 	}
 
 	/* Then free posted rx buffer that were not used */
@@ -1576,6 +1575,9 @@ static int be_rx_queues_create(struct be_adapter *adapter)
 	adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE;
 	for_all_rx_queues(adapter, rxo, i) {
 		rxo->adapter = adapter;
+		/* Init last_frag_index so that the frag index in the first
+		 * completion will never match */
+		rxo->last_frag_index = 0xffff;
 		rxo->rx_eq.max_eqd = BE_MAX_EQD;
 		rxo->rx_eq.enable_aic = true;
 
@@ -1697,10 +1699,9 @@ static irqreturn_t be_msix_tx_mcc(int irq, void *dev)
 	return IRQ_HANDLED;
 }
 
-static inline bool do_gro(struct be_adapter *adapter, struct be_rx_obj *rxo,
-			struct be_eth_rx_compl *rxcp)
+static inline bool do_gro(struct be_rx_obj *rxo,
+			struct be_eth_rx_compl *rxcp, u8 err)
 {
-	int err = AMAP_GET_BITS(struct amap_eth_rx_compl, err, rxcp);
 	int tcp_frame = AMAP_GET_BITS(struct amap_eth_rx_compl, tcpf, rxcp);
 
 	if (err)
@@ -1717,6 +1718,8 @@ static int be_poll_rx(struct napi_struct *napi, int budget)
 	struct be_queue_info *rx_cq = &rxo->cq;
 	struct be_eth_rx_compl *rxcp;
 	u32 work_done;
+	u16 frag_index, num_rcvd;
+	u8 err;
 
 	rxo->stats.rx_polls++;
 	for (work_done = 0; work_done < budget; work_done++) {
@@ -1724,10 +1727,22 @@ static int be_poll_rx(struct napi_struct *napi, int budget)
 		if (!rxcp)
 			break;
 
-		if (do_gro(adapter, rxo, rxcp))
-			be_rx_compl_process_gro(adapter, rxo, rxcp);
-		else
-			be_rx_compl_process(adapter, rxo, rxcp);
+		err = AMAP_GET_BITS(struct amap_eth_rx_compl, err, rxcp);
+		frag_index = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx,
+								rxcp);
+		num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags,
+								rxcp);
+
+		/* Skip out-of-buffer compl(lancer) or flush compl(BE) */
+		if (likely(frag_index != rxo->last_frag_index &&
+				num_rcvd != 0)) {
+			rxo->last_frag_index = frag_index;
+
+			if (do_gro(rxo, rxcp, err))
+				be_rx_compl_process_gro(adapter, rxo, rxcp);
+			else
+				be_rx_compl_process(adapter, rxo, rxcp);
+		}
 
 		be_rx_compl_reset(rxcp);
 	}
-- 
1.6.5.2


^ permalink raw reply related

* [Patch] net: kill an RCU warning in inet_fill_link_af()
From: Amerigo Wang @ 2010-12-01 11:14 UTC (permalink / raw)
  To: linux-kernel
  Cc: WANG Cong, David S. Miller, Alexey Kuznetsov, Pekka Savola (ipv6),
	James Morris, Hideaki YOSHIFUJI, Patrick McHardy, netdev

From: WANG Cong <amwang@redhat.com>

The latest net-next-2.6 triggers an RCU warning during boot,
lockdep complains that in inet_fill_link_af() we call rcu_dereference_check()
without rcu_read_lock() protection.

This patch fixes it by replacing __in_dev_get_rcu() with in_dev_get().

Signed-off-by: WANG Cong <amwang@redhat.com>

---
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index d9f71ba..73baed8 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1258,31 +1258,36 @@ errout:
 
 static size_t inet_get_link_af_size(const struct net_device *dev)
 {
-	struct in_device *in_dev = __in_dev_get_rcu(dev);
+	struct in_device *in_dev = in_dev_get(dev);
 
 	if (!in_dev)
 		return 0;
 
+	in_dev_put(in_dev);
 	return nla_total_size(IPV4_DEVCONF_MAX * 4); /* IFLA_INET_CONF */
 }
 
 static int inet_fill_link_af(struct sk_buff *skb, const struct net_device *dev)
 {
-	struct in_device *in_dev = __in_dev_get_rcu(dev);
+	struct in_device *in_dev = in_dev_get(dev);
 	struct nlattr *nla;
-	int i;
+	int i, ret = 0;
 
 	if (!in_dev)
 		return -ENODATA;
 
 	nla = nla_reserve(skb, IFLA_INET_CONF, IPV4_DEVCONF_MAX * 4);
-	if (nla == NULL)
-		return -EMSGSIZE;
+	if (nla == NULL) {
+		ret = -EMSGSIZE;
+		goto out;
+	}
 
 	for (i = 0; i < IPV4_DEVCONF_MAX; i++)
 		((u32 *) nla_data(nla))[i] = in_dev->cnf.data[i];
 
-	return 0;
+out:
+	in_dev_put(in_dev);
+	return ret;
 }
 
 static const struct nla_policy inet_af_policy[IFLA_INET_MAX+1] = {
@@ -1293,11 +1298,14 @@ static int inet_validate_link_af(const struct net_device *dev,
 				 const struct nlattr *nla)
 {
 	struct nlattr *a, *tb[IFLA_INET_MAX+1];
+	struct in_device *in_dev = in_dev_get(dev);
 	int err, rem;
 
-	if (dev && !__in_dev_get_rcu(dev))
+	if (dev && !in_dev)
 		return -EAFNOSUPPORT;
 
+	in_dev_put(in_dev);
+
 	err = nla_parse_nested(tb, IFLA_INET_MAX, nla, inet_af_policy);
 	if (err < 0)
 		return err;
@@ -1319,7 +1327,7 @@ static int inet_validate_link_af(const struct net_device *dev,
 
 static int inet_set_link_af(struct net_device *dev, const struct nlattr *nla)
 {
-	struct in_device *in_dev = __in_dev_get_rcu(dev);
+	struct in_device *in_dev = in_dev_get(dev);
 	struct nlattr *a, *tb[IFLA_INET_MAX+1];
 	int rem;
 
@@ -1334,6 +1342,7 @@ static int inet_set_link_af(struct net_device *dev, const struct nlattr *nla)
 			ipv4_devconf_set(in_dev, nla_type(a), nla_get_u32(a));
 	}
 
+	in_dev_put(in_dev);
 	return 0;
 }
 

^ permalink raw reply related

* Re: [Patch] bonding: clean up netpoll code
From: Cong Wang @ 2010-12-01 11:15 UTC (permalink / raw)
  To: Herbert Xu
  Cc: Eric Dumazet, linux-kernel, Jiri Pirko, Neil Horman, netdev,
	David S. Miller, Eric W. Biederman, bonding-devel, Jay Vosburgh,
	Stephen Hemminger
In-Reply-To: <20101201090621.GA11366@gondor.apana.org.au>

On 12/01/10 17:06, Herbert Xu wrote:
> On Wed, Dec 01, 2010 at 04:26:47PM +0800, Cong Wang wrote:
>>
>> Is this necessary?
>> It is just replacing checking IFF_IN_NETPOLL with netpoll_tx_running(),
>> you might need to take a look at the bridge code.
>
> I agree with Eric.  The patch does look pretty scary right now.
>
> Each patch should do one thing and one thing only.
>

Ok, I will separate that part out.

Thanks!

^ permalink raw reply

* Re: [Patch] net: kill an RCU warning in inet_fill_link_af()
From: Eric Dumazet @ 2010-12-01 11:21 UTC (permalink / raw)
  To: Amerigo Wang
  Cc: linux-kernel, David S. Miller, Alexey Kuznetsov,
	Pekka Savola (ipv6), James Morris, Hideaki YOSHIFUJI,
	Patrick McHardy, netdev
In-Reply-To: <1291202063-6239-1-git-send-email-amwang@redhat.com>

Le mercredi 01 décembre 2010 à 19:14 +0800, Amerigo Wang a écrit :
> From: WANG Cong <amwang@redhat.com>
> 
> The latest net-next-2.6 triggers an RCU warning during boot,
> lockdep complains that in inet_fill_link_af() we call rcu_dereference_check()
> without rcu_read_lock() protection.
> 
> This patch fixes it by replacing __in_dev_get_rcu() with in_dev_get().
> 
> Signed-off-by: WANG Cong <amwang@redhat.com>
> 

Sorry patch is not the right fix. Please take a look at commit 95ae6b22

We are working hard to remove all the not needed get()/put(), not to add
new ones ;)


> ---
> diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
> index d9f71ba..73baed8 100644
> --- a/net/ipv4/devinet.c
> +++ b/net/ipv4/devinet.c
> @@ -1258,31 +1258,36 @@ errout:
>  
>  static size_t inet_get_link_af_size(const struct net_device *dev)
>  {
> -	struct in_device *in_dev = __in_dev_get_rcu(dev);
> +	struct in_device *in_dev = in_dev_get(dev);
>  
>  	if (!in_dev)
>  		return 0;
>  
> +	in_dev_put(in_dev);
>  	return nla_total_size(IPV4_DEVCONF_MAX * 4); /* IFLA_INET_CONF */
>  }
>  

In this function why should we even take a reference, just to check if
pointer exists ?

If RTNL is held (I believe so), just use __in_dev_get_rtnl()

>  static int inet_fill_link_af(struct sk_buff *skb, const struct net_device *dev)
>  {
> -	struct in_device *in_dev = __in_dev_get_rcu(dev);
> +	struct in_device *in_dev = in_dev_get(dev);
>  	struct nlattr *nla;
> -	int i;
> +	int i, ret = 0;
>  
>  	if (!in_dev)
>  		return -ENODATA;
>  
>  	nla = nla_reserve(skb, IFLA_INET_CONF, IPV4_DEVCONF_MAX * 4);
> -	if (nla == NULL)
> -		return -EMSGSIZE;
> +	if (nla == NULL) {
> +		ret = -EMSGSIZE;
> +		goto out;
> +	}
>  
>  	for (i = 0; i < IPV4_DEVCONF_MAX; i++)
>  		((u32 *) nla_data(nla))[i] = in_dev->cnf.data[i];
>  
> -	return 0;
> +out:
> +	in_dev_put(in_dev);
> +	return ret;
>  }


In this function we hold RTNL...
 Please use __in_dev_get_rtnl()


>  
>  static const struct nla_policy inet_af_policy[IFLA_INET_MAX+1] = {
> @@ -1293,11 +1298,14 @@ static int inet_validate_link_af(const struct net_device *dev,
>  				 const struct nlattr *nla)
>  {
>  	struct nlattr *a, *tb[IFLA_INET_MAX+1];
> +	struct in_device *in_dev = in_dev_get(dev);
>  	int err, rem;
>  
> -	if (dev && !__in_dev_get_rcu(dev))
> +	if (dev && !in_dev)
>  		return -EAFNOSUPPORT;
>  
> +	in_dev_put(in_dev);
> +
>  	err = nla_parse_nested(tb, IFLA_INET_MAX, nla, inet_af_policy);
>  	if (err < 0)
>  		return err;
> @@ -1319,7 +1327,7 @@ static int inet_validate_link_af(const struct net_device *dev,
>  
>  static int inet_set_link_af(struct net_device *dev, const struct nlattr *nla)
>  {
> -	struct in_device *in_dev = __in_dev_get_rcu(dev);
> +	struct in_device *in_dev = in_dev_get(dev);
>  	struct nlattr *a, *tb[IFLA_INET_MAX+1];
>  	int rem;
>  
> @@ -1334,6 +1342,7 @@ static int inet_set_link_af(struct net_device *dev, const struct nlattr *nla)
>  			ipv4_devconf_set(in_dev, nla_type(a), nla_get_u32(a));
>  	}
>  
> +	in_dev_put(in_dev);
>  	return 0;
>  }

Same here. RTNL is held. Please use __in_dev_get_rtnl()

^ permalink raw reply

* [PATCH net-next-2.6] : __in_dev_get_rtnl() can use rtnl_dereference()
From: Eric Dumazet @ 2010-12-01 11:37 UTC (permalink / raw)
  To: Amerigo Wang
  Cc: linux-kernel, David S. Miller, Alexey Kuznetsov,
	Pekka Savola (ipv6), James Morris, Hideaki YOSHIFUJI,
	Patrick McHardy, netdev
In-Reply-To: <1291202476.2856.584.camel@edumazet-laptop>

Le mercredi 01 décembre 2010 à 12:21 +0100, Eric Dumazet a écrit :

> Same here. RTNL is held. Please use __in_dev_get_rtnl()

By the way we can use rtnl_dereference() in __in_dev_get_rtnl()

[PATCH net-next-2.6] : __in_dev_get_rtnl() can use rtnl_dereference()

If caller holds RTNL, we dont need a memory barrier
(smp_read_barrier_depends) included in rcu_dereference().

Just use rtnl_dereference() to properly document the assertions.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
 include/linux/inetdevice.h |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h
index 2b86eaf..ae8fdc5 100644
--- a/include/linux/inetdevice.h
+++ b/include/linux/inetdevice.h
@@ -222,7 +222,7 @@ static inline struct in_device *in_dev_get(const struct net_device *dev)
 
 static inline struct in_device *__in_dev_get_rtnl(const struct net_device *dev)
 {
-	return rcu_dereference_check(dev->ip_ptr, lockdep_rtnl_is_held());
+	return rtnl_dereference(dev->ip_ptr);
 }
 
 extern void in_dev_finish_destroy(struct in_device *idev);

^ permalink raw reply related

* [PATCH v2 1/2] af_packet: use vmalloc_to_page() instead for the addresss returned by vmalloc()
From: Changli Gao @ 2010-12-01 12:52 UTC (permalink / raw)
  To: David S. Miller
  Cc: Eric Dumazet, Jiri Pirko, Neil Horman, netdev, Changli Gao

The following commit causes the pgv->buffer may point to the memory
returned by vmalloc(). And we can't use virt_to_page() for the vmalloc
address.

This patch introduces a new inline function pgv_to_page(), which calls
vmalloc_to_page() for the vmalloc address, and virt_to_page() for the
__get_free_pages address.

We used to increase page pointer to get the next page at the next page
address, after Neil's patch, it is wrong, as the physical address may
be not continuous. This patch also fixes this issue.

    commit 0e3125c755445664f00ad036e4fc2cd32fd52877
    Author: Neil Horman <nhorman@tuxdriver.com>
    Date:   Tue Nov 16 10:26:47 2010 -0800

    packet: Enhance AF_PACKET implementation to not require high order contiguous memory allocation (v4)

Signed-off-by: Changli Gao <xiaosuo@gmail.com>
---
v2: fix the page incremental issue
 net/packet/af_packet.c |   36 +++++++++++++++++++-----------------
 1 file changed, 19 insertions(+), 17 deletions(-)
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 422705d..26fbeb1 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -224,6 +224,13 @@ struct packet_skb_cb {
 
 #define PACKET_SKB_CB(__skb)	((struct packet_skb_cb *)((__skb)->cb))
 
+static inline struct page *pgv_to_page(void *addr)
+{
+	if (is_vmalloc_addr(addr))
+		return vmalloc_to_page(addr);
+	return virt_to_page(addr);
+}
+
 static void __packet_set_status(struct packet_sock *po, void *frame, int status)
 {
 	union {
@@ -236,11 +243,11 @@ static void __packet_set_status(struct packet_sock *po, void *frame, int status)
 	switch (po->tp_version) {
 	case TPACKET_V1:
 		h.h1->tp_status = status;
-		flush_dcache_page(virt_to_page(&h.h1->tp_status));
+		flush_dcache_page(pgv_to_page(&h.h1->tp_status));
 		break;
 	case TPACKET_V2:
 		h.h2->tp_status = status;
-		flush_dcache_page(virt_to_page(&h.h2->tp_status));
+		flush_dcache_page(pgv_to_page(&h.h2->tp_status));
 		break;
 	default:
 		pr_err("TPACKET version not supported\n");
@@ -263,10 +270,10 @@ static int __packet_get_status(struct packet_sock *po, void *frame)
 	h.raw = frame;
 	switch (po->tp_version) {
 	case TPACKET_V1:
-		flush_dcache_page(virt_to_page(&h.h1->tp_status));
+		flush_dcache_page(pgv_to_page(&h.h1->tp_status));
 		return h.h1->tp_status;
 	case TPACKET_V2:
-		flush_dcache_page(virt_to_page(&h.h2->tp_status));
+		flush_dcache_page(pgv_to_page(&h.h2->tp_status));
 		return h.h2->tp_status;
 	default:
 		pr_err("TPACKET version not supported\n");
@@ -800,15 +807,11 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
 	__packet_set_status(po, h.raw, status);
 	smp_mb();
 	{
-		struct page *p_start, *p_end;
-		u8 *h_end = h.raw + macoff + snaplen - 1;
-
-		p_start = virt_to_page(h.raw);
-		p_end = virt_to_page(h_end);
-		while (p_start <= p_end) {
-			flush_dcache_page(p_start);
-			p_start++;
-		}
+		u8 *start, *end;
+
+		end = (u8 *)PAGE_ALIGN((unsigned long)h.raw + macoff + snaplen);
+		for (start = h.raw; start < end; start += PAGE_SIZE)
+			flush_dcache_page(pgv_to_page(start));
 	}
 
 	sk->sk_data_ready(sk, 0);
@@ -915,7 +918,6 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
 	}
 
 	err = -EFAULT;
-	page = virt_to_page(data);
 	offset = offset_in_page(data);
 	len_max = PAGE_SIZE - offset;
 	len = ((to_write > len_max) ? len_max : to_write);
@@ -934,11 +936,11 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
 			return -EFAULT;
 		}
 
+		page = pgv_to_page(data);
+		data += len;
 		flush_dcache_page(page);
 		get_page(page);
-		skb_fill_page_desc(skb,
-				nr_frags,
-				page++, offset, len);
+		skb_fill_page_desc(skb, nr_frags, page, offset, len);
 		to_write -= len;
 		offset = 0;
 		len_max = PAGE_SIZE;

^ permalink raw reply related

* [PATCH v2 2/2] af_packet: remove pgv.flags
From: Changli Gao @ 2010-12-01 12:52 UTC (permalink / raw)
  To: David S. Miller
  Cc: Eric Dumazet, Jiri Pirko, Neil Horman, netdev, Changli Gao

As we can check if an address is vmalloc address with is_vmalloc_addr(),
we remove pgv.flags. Then we may get more pg_vecs.

Signed-off-by: Changli Gao <xiaosuo@gmail.com>
---
v2: keep struct pgv
 net/packet/af_packet.c |   20 +++++---------------
 1 file changed, 5 insertions(+), 15 deletions(-)
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 26fbeb1..a11c731 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -167,7 +167,6 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req,
 #define PGV_FROM_VMALLOC 1
 struct pgv {
 	char *buffer;
-	unsigned char flags;
 };
 
 struct packet_ring_buffer {
@@ -2342,7 +2341,7 @@ static void free_pg_vec(struct pgv *pg_vec, unsigned int order,
 
 	for (i = 0; i < len; i++) {
 		if (likely(pg_vec[i].buffer)) {
-			if (pg_vec[i].flags & PGV_FROM_VMALLOC)
+			if (is_vmalloc_addr(pg_vec[i].buffer))
 				vfree(pg_vec[i].buffer);
 			else
 				free_pages((unsigned long)pg_vec[i].buffer,
@@ -2353,8 +2352,7 @@ static void free_pg_vec(struct pgv *pg_vec, unsigned int order,
 	kfree(pg_vec);
 }
 
-static inline char *alloc_one_pg_vec_page(unsigned long order,
-					  unsigned char *flags)
+static inline char *alloc_one_pg_vec_page(unsigned long order)
 {
 	char *buffer = NULL;
 	gfp_t gfp_flags = GFP_KERNEL | __GFP_COMP |
@@ -2368,7 +2366,6 @@ static inline char *alloc_one_pg_vec_page(unsigned long order,
 	/*
 	 * __get_free_pages failed, fall back to vmalloc
 	 */
-	*flags |= PGV_FROM_VMALLOC;
 	buffer = vzalloc((1 << order) * PAGE_SIZE);
 
 	if (buffer)
@@ -2377,7 +2374,6 @@ static inline char *alloc_one_pg_vec_page(unsigned long order,
 	/*
 	 * vmalloc failed, lets dig into swap here
 	 */
-	*flags = 0;
 	gfp_flags &= ~__GFP_NORETRY;
 	buffer = (char *)__get_free_pages(gfp_flags, order);
 	if (buffer)
@@ -2400,8 +2396,7 @@ static struct pgv *alloc_pg_vec(struct tpacket_req *req, int order)
 		goto out;
 
 	for (i = 0; i < block_nr; i++) {
-		pg_vec[i].buffer = alloc_one_pg_vec_page(order,
-							 &pg_vec[i].flags);
+		pg_vec[i].buffer = alloc_one_pg_vec_page(order);
 		if (unlikely(!pg_vec[i].buffer))
 			goto out_free_pgvec;
 	}
@@ -2585,13 +2580,8 @@ static int packet_mmap(struct file *file, struct socket *sock,
 			void *kaddr = rb->pg_vec[i].buffer;
 			int pg_num;
 
-			for (pg_num = 0; pg_num < rb->pg_vec_pages;
-					pg_num++) {
-				if (rb->pg_vec[i].flags & PGV_FROM_VMALLOC)
-					page = vmalloc_to_page(kaddr);
-				else
-					page = virt_to_page(kaddr);
-
+			for (pg_num = 0; pg_num < rb->pg_vec_pages; pg_num++) {
+				page = pgv_to_page(kaddr);
 				err = vm_insert_page(vma, start, page);
 				if (unlikely(err))
 					goto out;

^ permalink raw reply related

* Re: [PATCH 1/2] af_packet: use vmalloc_to_page() instead for the addresss returned by vmalloc()
From: Changli Gao @ 2010-12-01 13:05 UTC (permalink / raw)
  To: Neil Horman; +Cc: Eric Dumazet, David S. Miller, Jiri Pirko, netdev
In-Reply-To: <20101130143720.GA6017@hmsreliant.think-freely.org>

On Tue, Nov 30, 2010 at 10:37 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
> Off the top of my head, I would think that pgv_to_page could be prototyped such
> that it could accept addr, offset and struct page ** arguments.  That way we can
> track the current page that we're mapped to, lowering the number of calls to
> vmalloc_to_page, and we can still use an increment like we do above (as long as
> its wrapped in a subsequent call to pgv_to_page)

I'll try to optimize pgv_to_page() after this patch series merged. I
am planning to call vmalloc_to_page() previously, and cache its result
in a per pgv array for future use. Thanks.


-- 
Regards,
Changli Gao(xiaosuo@gmail.com)

^ permalink raw reply

* Re: [PATCH 1/2] af_packet: use vmalloc_to_page() instead for the addresss returned by vmalloc()
From: Eric Dumazet @ 2010-12-01 13:38 UTC (permalink / raw)
  To: Changli Gao; +Cc: Neil Horman, David S. Miller, Jiri Pirko, netdev
In-Reply-To: <AANLkTim7SSRMkhc_eMz+Bk12kAwfG==j-dH4NOPu-uS2@mail.gmail.com>

Le mercredi 01 décembre 2010 à 21:05 +0800, Changli Gao a écrit :
> On Tue, Nov 30, 2010 at 10:37 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
> > Off the top of my head, I would think that pgv_to_page could be prototyped such
> > that it could accept addr, offset and struct page ** arguments.  That way we can
> > track the current page that we're mapped to, lowering the number of calls to
> > vmalloc_to_page, and we can still use an increment like we do above (as long as
> > its wrapped in a subsequent call to pgv_to_page)
> 
> I'll try to optimize pgv_to_page() after this patch series merged. I
> am planning to call vmalloc_to_page() previously, and cache its result
> in a per pgv array for future use. Thanks.
> 
> 

Hmm... fact is flush_dcache_page() is void on some arches.

Maybe the only thing to do is avoid pgv_to_page() calls if
ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE is 0

    The ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE symbol was introduced to avoid
    pointless empty cache-thrashing loops on architectures for which
    flush_dcache_page() is a no-op.  Every architecture was provided with this
    flush pages on architectires where ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE is
    equal 1 or do nothing otherwise.




^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox