Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH 0/5] Candidate fix for increased number of GFP_ATOMIC failures V2
From: Mel LKML @ 2009-10-24 13:46 UTC (permalink / raw)
  To: Karol Lewandowski
  Cc: Mel Gorman, Frans Pop, Jiri Kosina, Sven Geggus, Tobias Oetiker,
	Rafael J. Wysocki, David Miller, Reinette Chatre, Kalle Valo,
	David Rientjes, KOSAKI Motohiro, Mohamed Abbas, Jens Axboe,
	John W. Linville, Pekka Enberg, Bartlomiej Zolnierkiewicz,
	Greg Kroah-Hartman, Stephan von Krawczynski, Kernel Testers List,
	netdev, linux-kernel, linux-mm@kvack.org
In-Reply-To: <20091023211239.GA6185@bizet.domek.prywatny>

Hi,

This is the same Mel as mel@csn.ul.ie. The mail server the address is
on has no power until Tuesday so I'm not going to be very unresponsive
until then. Monday is also a public holiday here and apparently they
are upgrading the power transformers near the building.

On 10/23/09, Karol Lewandowski <karol.k.lewandowski@gmail.com> wrote:
> On Fri, Oct 23, 2009 at 06:58:10PM +0200, Karol Lewandowski wrote:
>> On Thu, Oct 22, 2009 at 03:22:31PM +0100, Mel Gorman wrote:
>> > Test 3: If you are getting allocation failures, try with the following
>> > patch
>> >
>> >   3/5 vmscan: Force kswapd to take notice faster when high-order
>> > watermarks are being hit
>
>> No, problem doesn't go away with these patches (1+2+3).  However, from
>> my testing this particular patch makes it way, way harder to trigger
>> allocation failures (but these are still present).
>>
>> This bothers me - should I test following patches with or without
>> above patch?  This patch makes bug harder to find, IMVHO it doesn't
>> fix the real problem.
> ..
>
>> Test 4: If you are still getting failures, apply the following
>>  4/5 page allocator: Pre-emptively wake kswapd when high-order watermarks
>> are hit
>
> Ok, I've tested patches 1+2+4 and bug, while very hard to trigger, is
> still present. I'll test complete 1-4 patchset as time permits.
>

And also patch 5 please which is the revert. Patch 5 as pointed out is
probably a red herring. Hwoever, it has changed the timing and made a
difference for some testing so I'd like to know if it helps yours as
well.

As things stand, it looks like patches 1+2 should certainly go ahead.
I need to give more thought on patches 3 and 4 as to why they help
Tobias but not anyone elses testing.

Thanks

--
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/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [RFC] [PATCH] udp: Don't save dst in udpv6_sendmsg()
From: Krishna Kumar2 @ 2009-10-24 13:45 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, netdev-owner
In-Reply-To: <20091024.064010.145864194.davem@davemloft.net>

David Miller wrote on 10/24/2009 07:10:10 PM:
>
> > Performance: I ran netperf UDPv6 RR to use connected sockets.
> > Tested with a 70 min run, aggregate of 5 netperf runs for
> > each result.
>
> Who actually uses connected UDP sockets? :-)

Just something I found when running netperf RR tests, and the code is there
doing it anyway. Maybe I can drop doing this testing, but upto you.

Thanks,

- KK


^ permalink raw reply

* Re: PATCH 23/10]Optimize the upload speed for PPP connection.
From: David Miller @ 2009-10-24 13:46 UTC (permalink / raw)
  To: william.allen.simpson; +Cc: huananhu, netdev, linux-kernel, zihan, greg, haegar
In-Reply-To: <4AE19780.3020507@gmail.com>

From: William Allen Simpson <william.allen.simpson@gmail.com>
Date: Fri, 23 Oct 2009 07:46:08 -0400

> Concur.  I'd go further than that, my code usually made room for at
> least
> a full MTU (MRU) with HDLC escaping.  To minimize context switches,
> that
> should be 3014 ((1500 MRU + 2 FCS + 4 header) * 2 escapes + 2 flags).
> 
> Even in the old days, when memory was tight, context switches and
> interrupt
> time were more expensive, too.  PPP is supposed to scale to OC-192.

Actually I'd like to see ->obuf allocated externally and then
make it simply PAGE_SIZE.

^ permalink raw reply

* iwl3945, after a while stops working with "No space for Tx"
From: Frederik Nosi @ 2009-10-24 13:44 UTC (permalink / raw)
  To: Zhu Yi, Reinette Chatre, Intel Linux Wireless, John W. Linville,
	Tomas Winkler <tomas.
  Cc: netdev, linux-kernel

Hi,
first sorry if somebody is not the right contact, got the adressess from ./scripts/get_maintainer.pl -f drivers/net/wireless/iwlwifi.
>From some kernel versions now, after some time that im using this card it stops working and on messages i get this errors:

Oct 24 14:38:24 kotys NetworkManager: <info>  Activation (wlan0) Stage 5 of 5 (IP Configure Commit) complete.
[snip pulseaudio's stuppid log spam warning]
Oct 24 14:40:07 kotys kernel: iwl3945 0000:04:00.0: Error sending REPLY_TX_PWR_TABLE_CMD: time out after 500ms.
Oct 24 14:40:09 kotys pulseaudio[16469]: sap.c: sendmsg() failed: Invalid argument
Oct 24 14:40:10 kotys kernel: iwl3945 0000:04:00.0: Error sending REPLY_SCAN_CMD: time out after 500ms.
Oct 24 14:40:11 kotys kernel: iwl3945 0000:04:00.0: Error sending REPLY_TX_PWR_TABLE_CMD: time out after 500ms.
Oct 24 14:40:11 kotys kernel: iwl3945 0000:04:00.0: Error sending POWER_TABLE_CMD: time out after 500ms.
Oct 24 14:40:14 kotys kernel: iwl3945 0000:04:00.0: set power fail, ret = -110
Oct 24 14:40:14 kotys kernel: No probe response from AP 00:1c:df:82:63:c9 after 500ms, disconnecting.
Oct 24 14:40:14 kotys NetworkManager: <info>  (wlan0): supplicant connection state:  completed -> disconnected
Oct 24 14:40:14 kotys NetworkManager: <info>  (wlan0): supplicant connection state:  disconnected -> scanning
Oct 24 14:40:14 kotys pulseaudio[16469]: sap.c: sendmsg() failed: Invalid argument
Oct 24 14:40:14 kotys kernel: iwl3945 0000:04:00.0: Error sending REPLY_RXON: time out after 500ms.
Oct 24 14:40:14 kotys kernel: iwl3945 0000:04:00.0: Error setting new configuration (-110).
Oct 24 14:40:15 kotys kernel: iwl3945 0000:04:00.0: Error sending REPLY_SCAN_CMD: time out after 500ms.
Oct 24 14:40:15 kotys kernel: wlan0: direct probe to AP 00:1c:df:82:63:c9 (try 1)
Oct 24 14:40:15 kotys NetworkManager: <info>  (wlan0): supplicant connection state:  scanning -> associating
Oct 24 14:40:15 kotys kernel: wlan0: direct probe to AP 00:1c:df:82:63:c9 (try 2)
Oct 24 14:40:15 kotys kernel: wlan0: direct probe to AP 00:1c:df:82:63:c9 (try 3)
Oct 24 14:40:15 kotys kernel: iwl3945 0000:04:00.0: Error sending REPLY_RXON: time out after 500ms.
Oct 24 14:40:15 kotys kernel: iwl3945 0000:04:00.0: Error setting new configuration (-110).
Oct 24 14:40:15 kotys kernel: wlan0: direct probe to AP 00:1c:df:82:63:c9 timed out
Oct 24 14:40:16 kotys kernel: iwl3945 0000:04:00.0: Error sending REPLY_TX_PWR_TABLE_CMD: time out after 500ms.
Oct 24 14:40:16 kotys kernel: iwl3945 0000:04:00.0: Error sending REPLY_RXON: time out after 500ms.
Oct 24 14:40:16 kotys kernel: iwl3945 0000:04:00.0: Error setting new configuration (-110).


When this happens i am able to use the card only after reloading the related modules, iwl3945 ecc. But the problem happens again after some minutes that im connected.

Kernel is 2.6.32-rc5 but his started happening around 2.6.31, not sure exactly what version as i update kernel often. Firmware is iwl3945-ucode-15.32.2.9.

Every other info that you need just ask. I hope i dont have to bisect as this is the laptop i use for work too, but if it's needed i'll do.

I'm not subscribed on any ML, so in case please cc me.

Thanks for all the work!

F.



      

^ permalink raw reply

* Re: [RFC] [PATCH] udp: Don't save dst in udpv6_sendmsg()
From: David Miller @ 2009-10-24 13:40 UTC (permalink / raw)
  To: krkumar2; +Cc: netdev
In-Reply-To: <20091023111336.4733.4901.sendpatchset@localhost.localdomain>

From: Krishna Kumar <krkumar2@in.ibm.com>
Date: Fri, 23 Oct 2009 16:43:36 +0530

> Performance: I ran netperf UDPv6 RR to use connected sockets.
> Tested with a 70 min run, aggregate of 5 netperf runs for
> each result.

Who actually uses connected UDP sockets? :-)

^ permalink raw reply

* Re: [PATCH net-next-2.6] xfrm6_tunnel: RCU conversion
From: Eric Dumazet @ 2009-10-24 13:34 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, yoshfuji
In-Reply-To: <20091024.060920.258223911.davem@davemloft.net>

David Miller a écrit :
> Nice work Eric, I applied all of your RCU conversions to
> net-next-2.6, thanks!
> 
> Applying: ipv6 sit: RCU conversion phase I
> Applying: ipv6 sit: RCU conversion phase II
> Applying: xfrm6_tunnel: RCU conversion
> Applying: ipip: convert hash tables locking to RCU
> Applying: ip6tnl: convert hash tables locking to RCU
> Applying: gre: convert hash tables locking to RCU

Thanks a lot !



^ permalink raw reply

* Re: Irq architecture for multi-core network driver.
From: David Miller @ 2009-10-24 13:26 UTC (permalink / raw)
  To: ebiederm
  Cc: jesse.brandeburg, ddaney, cfriesen, netdev, linux-kernel,
	linux-mips
In-Reply-To: <m17huln1ab.fsf@fess.ebiederm.org>

From: ebiederm@xmission.com (Eric W. Biederman)
Date: Fri, 23 Oct 2009 16:22:36 -0700

> irqbalance is actually more likely to move irqs than the hardware.
> I have heard promises it won't move network irqs but I have seen
> the opposite behavior.

It knows what network devices are named, and looks for those keys
in /proc/interrupts.  Anything names 'ethN' will not be moved and
if you name them on a per-queue basis properly (ie. 'ethN-RX1' etc.)
it will flat distribute those interrupts amongst the cpus in the
machine.

So if you're doing "silly stuff" and naming your devices by some other
convention, you would end up defeating the detations built into
irqbalanced.

Actually, let's not even guess, go check out the sources of the
irqbalanced running on your system and make sure it has the network
device logic in it. :-)

^ permalink raw reply

* Re: Irq architecture for multi-core network driver.
From: David Miller @ 2009-10-24 13:23 UTC (permalink / raw)
  To: ddaney; +Cc: cfriesen, netdev, linux-kernel, linux-mips
In-Reply-To: <4AE0DB98.1000101@caviumnetworks.com>

From: David Daney <ddaney@caviumnetworks.com>
Date: Thu, 22 Oct 2009 15:24:24 -0700

> Certainly this is one mode of operation that should be supported, but
> I would also like to be able to go for raw throughput and have as many
> cores as possible reading from a single queue (like I currently have).

You can't do this, at least within the same flow, since as you even
mention in your original posting this can result in packet reordering
which we must avoid as much as is possible.

^ permalink raw reply

* Request: how do packet routing based on input gateway
From: Luca Dionisi @ 2009-10-24 13:22 UTC (permalink / raw)
  To: netdev, linux-net

Hi all

I must instruct my server to route packets based on destination prefix
and on the gateway from which the packet arrived.
E.g.
 I am 192.168.0.1
 a packet for 192.168.1.0/24 which arrived from gateway 192.168.0.2
must go through 192.168.1.1 dev eth0
 a packet for 192.168.1.0/24 which arrived from gateway 192.168.0.3
must go through 192.168.1.2 dev eth1
 a packet for 192.168.1.0/24 which arrived from any other gateway must
go through 192.168.1.3 dev eth2

The gateway I mean is just the last hop traversed, before me. It's not
necessarily the source of the packet.

How am I supposed to do that?

Regards.
Luca Dionisi

^ permalink raw reply

* Re: [PATCH] atm: Cleanup redundant tests on unsigned
From: David Miller @ 2009-10-24 13:19 UTC (permalink / raw)
  To: eric.dumazet; +Cc: roel.kluin, chas, netdev, akpm
In-Reply-To: <4AE1D4FE.5090902@gmail.com>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Fri, 23 Oct 2009 18:08:30 +0200

> Roel Kluin a écrit :
>> The variables are unsigned so the `< 0' test always fails, the
>> other part of the test catches wrapped values.
>> 
>> Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
>> ---
> 
> I believe such patches were posted in the past.
> 
> General consensus is that compiler is able to do this optimization for us,
> and reader doesnt have to ask to himself : "Is the test safe enough ?"

Conversely, the reader can say "Wow this can be negative?  There's
tests missing elsewhere! ... oh, nevermind it's unsigned"

That really wastes people's time too.

I suspect I'll apply these patches. :-)


^ permalink raw reply

* Re: [PATCH net-next-2.6] rtnetlink: speedup rtnl_dump_ifinfo()
From: David Miller @ 2009-10-24 13:13 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev, bcrl
In-Reply-To: <4AE06D81.4050003@gmail.com>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 22 Oct 2009 16:34:41 +0200

> When handling large number of netdevice, rtnl_dump_ifinfo()
> is very slow because it has O(N^2) complexity.
> 
> Instead of scanning one single list, we can use the 256 sub lists
> of the dev_index hash table.
> 
> This considerably speedups "ip link" operations
> 
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>

Applied, thanks!

^ permalink raw reply

* Re: [RFC] net,socket: introduce build_sockaddr_check helper to catch overflow at build time
From: David Miller @ 2009-10-24 13:12 UTC (permalink / raw)
  To: gorcunov; +Cc: netdev
In-Reply-To: <20091023214306.GA30616@lenovo>

From: Cyrill Gorcunov <gorcunov@gmail.com>
Date: Sat, 24 Oct 2009 01:43:06 +0400

> Or say it could be something like that
> 
> #define __sockaddr(type, src)	\
> 	({ build_sockaddr_check(sizeof(type)); (type *) src; })
> 
> and say in function af_inet.c:inet_getname instead of
> 
> 	struct sockaddr_in *sin	= (struct sockaddr_in *)uaddr;
> 
> we may write like
> 
> 	struct sockaddr_in *sin	= __sockaddr(struct sockaddr_in, uaddr);
> 
> which would check the size.

Or even a "DECLARE_SOCKADDR(type, src, dest)" which encapsulates the
entire declaration statement.

^ permalink raw reply

* Re: [PATCH net-next-2.6] xfrm6_tunnel: RCU conversion
From: David Miller @ 2009-10-24 13:09 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev, yoshfuji
In-Reply-To: <4AE28047.1020904@gmail.com>


Nice work Eric, I applied all of your RCU conversions to
net-next-2.6, thanks!

Applying: ipv6 sit: RCU conversion phase I
Applying: ipv6 sit: RCU conversion phase II
Applying: xfrm6_tunnel: RCU conversion
Applying: ipip: convert hash tables locking to RCU
Applying: ip6tnl: convert hash tables locking to RCU
Applying: gre: convert hash tables locking to RCU

^ permalink raw reply

* Re: [PATCH 00/27] sfc: Cleanup and preparation for new hardware
From: David Miller @ 2009-10-24 11:29 UTC (permalink / raw)
  To: bhutchings; +Cc: netdev, linux-net-drivers
In-Reply-To: <1256322441.2785.3.camel@achroite>

From: Ben Hutchings <bhutchings@solarflare.com>
Date: Fri, 23 Oct 2009 19:27:21 +0100

> This is a mixture of small cleanups, refactoring, renaming and an update
> to the register definitions.  There's more to come, in particular
> support for the new hardware, but I'll let you digest this batch first.

All applied, thanks Ben.

^ permalink raw reply

* Re: [PATCH] net: allow netdev_wait_allrefs() to run faster
From: Eric Dumazet @ 2009-10-24  8:49 UTC (permalink / raw)
  To: paulmck; +Cc: Octavian Purdila, Benjamin LaHaise, netdev, Cosmin Ratiu
In-Reply-To: <20091024054943.GA6638@linux.vnet.ibm.com>

Paul E. McKenney a écrit :
> On Sat, Oct 24, 2009 at 06:35:53AM +0200, Eric Dumazet wrote:
> 
>> Maybe we could call it once only, if we had to call 1 times
>> the jiffie delay ?
> 
> This could be a very useful approach!
> 
> However, please keep in mind that although synchronize_rcu_expedited()
> forces a grace period, it does nothing to speed the invocation of other
> RCU callbacks.  In short, synchronize_rcu_expedited() is a faster version
> of synchronize_rcu(), but doesn't necessarily help other synchronize_rcu()
> or call_rcu() invocations.
> 
> The reason I point this out is that it looks to me that the code below is
> waiting for some other task which is in turn waiting on a grace period.
> But I don't know this code, so could easily be confused.
> 

Normally, we need a synchronize_rcu() calls, but I feel its bit more than really
needed here.

On my dev machine, a synchronize_rcu() lasts between 2 an 12 ms


messages:Oct 21 19:13:14 svivoipvnx001-00 kernel: [ 2515.580259] synchronize_net() 4045596 ns
messages:Oct 21 19:13:14 svivoipvnx001-00 kernel: [ 2515.588262] synchronize_net() 7769327 ns
messages:Oct 21 19:13:14 svivoipvnx001-00 kernel: [ 2515.625014] synchronize_net() 4772052 ns
messages:Oct 21 19:13:14 svivoipvnx001-00 kernel: [ 2515.633008] synchronize_net() 7773896 ns
messages:Oct 21 19:13:14 svivoipvnx001-00 kernel: [ 2515.669260] synchronize_net() 3958141 ns
messages:Oct 21 19:13:14 svivoipvnx001-00 kernel: [ 2515.677259] synchronize_net() 7755817 ns
messages:Oct 21 19:13:14 svivoipvnx001-00 kernel: [ 2515.712011] synchronize_net() 2502544 ns
messages:Oct 21 19:13:14 svivoipvnx001-00 kernel: [ 2515.720011] synchronize_net() 7767748 ns
messages:Oct 21 19:13:14 svivoipvnx001-00 kernel: [ 2515.754259] synchronize_net() 2087946 ns
messages:Oct 21 19:13:14 svivoipvnx001-00 kernel: [ 2515.762258] synchronize_net() 7738054 ns
messages:Oct 21 19:13:14 svivoipvnx001-00 kernel: [ 2515.796011] synchronize_net() 3392760 ns
messages:Oct 21 19:13:15 svivoipvnx001-00 kernel: [ 2515.808025] synchronize_net() 11814619 ns
messages:Oct 21 19:13:15 svivoipvnx001-00 kernel: [ 2515.848010] synchronize_net() 8970220 ns
messages:Oct 21 19:13:15 svivoipvnx001-00 kernel: [ 2515.856015] synchronize_net() 7800782 ns
messages:Oct 21 19:13:15 svivoipvnx001-00 kernel: [ 2515.893008] synchronize_net() 6650174 ns
messages:Oct 21 19:13:15 svivoipvnx001-00 kernel: [ 2515.897012] synchronize_net() 3744808 ns
messages:Oct 21 19:13:15 svivoipvnx001-00 kernel: [ 2515.940202] synchronize_net() 8354366 ns
messages:Oct 21 19:13:15 svivoipvnx001-00 kernel: [ 2515.952137] synchronize_net() 11693215 ns
messages:Oct 21 19:13:15 svivoipvnx001-00 kernel: [ 2515.985010] synchronize_net() 2355970 ns
messages:Oct 21 19:13:15 svivoipvnx001-00 kernel: [ 2515.989009] synchronize_net() 3771419 ns
messages:Oct 21 19:13:15 svivoipvnx001-00 kernel: [ 2516.028137] synchronize_net() 7661195 ns
messages:Oct 21 19:13:15 svivoipvnx001-00 kernel: [ 2516.036152] synchronize_net() 7800056 ns
messages:Oct 21 19:13:15 svivoipvnx001-00 kernel: [ 2516.083135] synchronize_net() 6774026 ns
messages:Oct 21 19:13:15 svivoipvnx001-00 kernel: [ 2516.089145] synchronize_net() 5727189 ns
messages:Oct 21 19:13:15 svivoipvnx001-00 kernel: [ 2516.130385] synchronize_net() 10133932 ns
messages:Oct 21 19:13:15 svivoipvnx001-00 kernel: [ 2516.134399] synchronize_net() 3773058 ns
messages:Oct 21 19:13:15 svivoipvnx001-00 kernel: [ 2516.170136] synchronize_net() 4479194 ns
messages:Oct 21 19:13:15 svivoipvnx001-00 kernel: [ 2516.178138] synchronize_net() 7710466 ns
messages:Oct 21 19:13:15 svivoipvnx001-00 kernel: [ 2516.217198] synchronize_net() 4323437 ns
messages:Oct 21 19:13:15 svivoipvnx001-00 kernel: [ 2516.226206] synchronize_net() 8723108 ns
messages:Oct 21 19:13:15 svivoipvnx001-00 kernel: [ 2516.268013] synchronize_net() 6221155 ns
messages:Oct 21 19:13:15 svivoipvnx001-00 kernel: [ 2516.280007] synchronize_net() 11719297 ns
messages:Oct 21 19:13:15 svivoipvnx001-00 kernel: [ 2516.324008] synchronize_net() 11654511 ns
messages:Oct 21 19:13:15 svivoipvnx001-00 kernel: [ 2516.332009] synchronize_net() 7744182 ns


^ permalink raw reply

* Re: [PATCH 0/5] Candidate fix for increased number of GFP_ATOMIC failures V2
From: Pekka Enberg @ 2009-10-24  6:48 UTC (permalink / raw)
  To: Christoph Lameter
  Cc: Mel Gorman, Frans Pop, Jiri Kosina, Sven Geggus,
	Karol Lewandowski, Tobias Oetiker, Rafael J. Wysocki,
	David Miller, Reinette Chatre, Kalle Valo, David Rientjes,
	KOSAKI Motohiro, Mohamed Abbas, Jens Axboe, John W. Linville,
	Bartlomiej Zolnierkiewicz, Greg Kroah-Hartman,
	Stephan von Krawczynski, Kernel Testers List,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	" \" <linux-mm-Bw31MaZKKs3YtjvyW6yDsg@public.gmane.org>, akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org, torvalds@l
In-Reply-To: <alpine.DEB.1.10.0910232151380.2001@V090114053VZO-1>

On Thu, 22 Oct 2009, Pekka Enberg wrote:
>> These are pretty obvious bug fixes and should go to linux-next ASAP IMHO.

Christoph Lameter wrote:
> Bug fixes go into main not linux-next. Lets make sure these fixes really
> work and then merge.

Regardless, patches 1-2 and should _really_ go to Linus' tree (and 
eventually -stable) while we figure out the rest of the problems. They 
fix obvious regressions in the code paths and we have reports from 
people that they help. Yes, they don't fix everything for everyone but 
we there's no upside in holding back fixes that are simple one line 
fixes to regressions.

		Pekka

^ permalink raw reply

* Re: [PATCH] net: allow netdev_wait_allrefs() to run faster
From: Paul E. McKenney @ 2009-10-24  5:49 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Octavian Purdila, Benjamin LaHaise, netdev, Cosmin Ratiu
In-Reply-To: <4AE28429.6040608@gmail.com>

On Sat, Oct 24, 2009 at 06:35:53AM +0200, Eric Dumazet wrote:
> Paul E. McKenney a écrit :
> > On Wed, Oct 21, 2009 at 05:40:07PM +0200, Eric Dumazet wrote:
> >> [PATCH] net: allow netdev_wait_allrefs() to run faster
> >>
> >> netdev_wait_allrefs() waits that all references to a device vanishes.
> >>
> >> It currently uses a _very_ pessimistic 250 ms delay between each probe.
> >> Some users report that no more than 4 devices can be dismantled per second,
> >> this is a pretty serious problem for extreme setups.
> >>
> >> Most likely, references only wait for a rcu grace period that should come
> >> fast, so use a schedule_timeout_uninterruptible(1) to allow faster recovery.
> > 
> > Is this a place where synchronize_rcu_expedited() is appropriate?
> > (It went in to 2.6.32-rc1.)
> 
> Thanks for the tip Paul
> 
> I believe netdev_wait_allrefs() is not a perfect candidate, because 
> synchronize_sched_expedited() seems really expensive.

It does indeed keep the CPUs quite busy for a bit.  ;-)

> Maybe we could call it once only, if we had to call 1 times
> the jiffie delay ?

This could be a very useful approach!

However, please keep in mind that although synchronize_rcu_expedited()
forces a grace period, it does nothing to speed the invocation of other
RCU callbacks.  In short, synchronize_rcu_expedited() is a faster version
of synchronize_rcu(), but doesn't necessarily help other synchronize_rcu()
or call_rcu() invocations.

The reason I point this out is that it looks to me that the code below is
waiting for some other task which is in turn waiting on a grace period.
But I don't know this code, so could easily be confused.

						Thanx, paul

> diff --git a/net/core/dev.c b/net/core/dev.c
> index fa88dcd..9b04b9a 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -4970,6 +4970,7 @@ EXPORT_SYMBOL(register_netdev);
>  static void netdev_wait_allrefs(struct net_device *dev)
>  {
>  	unsigned long rebroadcast_time, warning_time;
> +	unsigned int count = 0;
> 
>  	rebroadcast_time = warning_time = jiffies;
>  	while (atomic_read(&dev->refcnt) != 0) {
> @@ -4995,7 +4996,10 @@ static void netdev_wait_allrefs(struct net_device *dev)
>  			rebroadcast_time = jiffies;
>  		}
> 
> -		msleep(250);
> +		if (count++ == 1)
> +			synchronize_rcu_expedited();
> +		else
> +			schedule_timeout_uninterruptible(1);
> 
>  		if (time_after(jiffies, warning_time + 10 * HZ)) {
>  			printk(KERN_EMERG "unregister_netdevice: "
> 

^ permalink raw reply

* Re: [PATCH] net: allow netdev_wait_allrefs() to run faster
From: Eric Dumazet @ 2009-10-24  4:35 UTC (permalink / raw)
  To: paulmck; +Cc: Octavian Purdila, Benjamin LaHaise, netdev, Cosmin Ratiu
In-Reply-To: <20091023211338.GA6145@linux.vnet.ibm.com>

Paul E. McKenney a écrit :
> On Wed, Oct 21, 2009 at 05:40:07PM +0200, Eric Dumazet wrote:
>> [PATCH] net: allow netdev_wait_allrefs() to run faster
>>
>> netdev_wait_allrefs() waits that all references to a device vanishes.
>>
>> It currently uses a _very_ pessimistic 250 ms delay between each probe.
>> Some users report that no more than 4 devices can be dismantled per second,
>> this is a pretty serious problem for extreme setups.
>>
>> Most likely, references only wait for a rcu grace period that should come
>> fast, so use a schedule_timeout_uninterruptible(1) to allow faster recovery.
> 
> Is this a place where synchronize_rcu_expedited() is appropriate?
> (It went in to 2.6.32-rc1.)
> 

Thanks for the tip Paul

I believe netdev_wait_allrefs() is not a perfect candidate, because 
synchronize_sched_expedited() seems really expensive.

Maybe we could call it once only, if we had to call 1 times
the jiffie delay ?

diff --git a/net/core/dev.c b/net/core/dev.c
index fa88dcd..9b04b9a 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4970,6 +4970,7 @@ EXPORT_SYMBOL(register_netdev);
 static void netdev_wait_allrefs(struct net_device *dev)
 {
 	unsigned long rebroadcast_time, warning_time;
+	unsigned int count = 0;
 
 	rebroadcast_time = warning_time = jiffies;
 	while (atomic_read(&dev->refcnt) != 0) {
@@ -4995,7 +4996,10 @@ static void netdev_wait_allrefs(struct net_device *dev)
 			rebroadcast_time = jiffies;
 		}
 
-		msleep(250);
+		if (count++ == 1)
+			synchronize_rcu_expedited();
+		else
+			schedule_timeout_uninterruptible(1);
 
 		if (time_after(jiffies, warning_time + 10 * HZ)) {
 			printk(KERN_EMERG "unregister_netdevice: "


^ permalink raw reply related

* [PATCH net-next-2.6] xfrm6_tunnel: RCU conversion
From: Eric Dumazet @ 2009-10-24  4:19 UTC (permalink / raw)
  To: David S. Miller; +Cc: Linux Netdev List, Yoshifuji Hideaki

xfrm6_tunnels use one rwlock to protect their hash tables.

Plain and straightforward conversion to RCU locking to permit better SMP
performance.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
--- 
 net/ipv6/xfrm6_tunnel.c |   47 ++++++++++++++++++++++----------------
 1 files changed, 28 insertions(+), 19 deletions(-)

diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index 81a95c0..438831d 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -23,7 +23,7 @@
  */
 #include <linux/module.h>
 #include <linux/xfrm.h>
-#include <linux/list.h>
+#include <linux/rculist.h>
 #include <net/ip.h>
 #include <net/xfrm.h>
 #include <net/ipv6.h>
@@ -36,14 +36,15 @@
  * per xfrm_address_t.
  */
 struct xfrm6_tunnel_spi {
-	struct hlist_node list_byaddr;
-	struct hlist_node list_byspi;
-	xfrm_address_t addr;
-	u32 spi;
-	atomic_t refcnt;
+	struct hlist_node	list_byaddr;
+	struct hlist_node	list_byspi;
+	xfrm_address_t		addr;
+	u32			spi;
+	atomic_t		refcnt;
+	struct rcu_head		rcu_head;
 };
 
-static DEFINE_RWLOCK(xfrm6_tunnel_spi_lock);
+static DEFINE_SPINLOCK(xfrm6_tunnel_spi_lock);
 
 static u32 xfrm6_tunnel_spi;
 
@@ -107,6 +108,7 @@ static void xfrm6_tunnel_spi_fini(void)
 		if (!hlist_empty(&xfrm6_tunnel_spi_byspi[i]))
 			return;
 	}
+	rcu_barrier();
 	kmem_cache_destroy(xfrm6_tunnel_spi_kmem);
 	xfrm6_tunnel_spi_kmem = NULL;
 }
@@ -116,7 +118,7 @@ static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
 	struct xfrm6_tunnel_spi *x6spi;
 	struct hlist_node *pos;
 
-	hlist_for_each_entry(x6spi, pos,
+	hlist_for_each_entry_rcu(x6spi, pos,
 			     &xfrm6_tunnel_spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)],
 			     list_byaddr) {
 		if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0)
@@ -131,10 +133,10 @@ __be32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
 	struct xfrm6_tunnel_spi *x6spi;
 	u32 spi;
 
-	read_lock_bh(&xfrm6_tunnel_spi_lock);
+	rcu_read_lock_bh();
 	x6spi = __xfrm6_tunnel_spi_lookup(saddr);
 	spi = x6spi ? x6spi->spi : 0;
-	read_unlock_bh(&xfrm6_tunnel_spi_lock);
+	rcu_read_unlock_bh();
 	return htonl(spi);
 }
 
@@ -185,14 +187,15 @@ alloc_spi:
 	if (!x6spi)
 		goto out;
 
+	INIT_RCU_HEAD(&x6spi->rcu_head);
 	memcpy(&x6spi->addr, saddr, sizeof(x6spi->addr));
 	x6spi->spi = spi;
 	atomic_set(&x6spi->refcnt, 1);
 
-	hlist_add_head(&x6spi->list_byspi, &xfrm6_tunnel_spi_byspi[index]);
+	hlist_add_head_rcu(&x6spi->list_byspi, &xfrm6_tunnel_spi_byspi[index]);
 
 	index = xfrm6_tunnel_spi_hash_byaddr(saddr);
-	hlist_add_head(&x6spi->list_byaddr, &xfrm6_tunnel_spi_byaddr[index]);
+	hlist_add_head_rcu(&x6spi->list_byaddr, &xfrm6_tunnel_spi_byaddr[index]);
 out:
 	return spi;
 }
@@ -202,26 +205,32 @@ __be32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr)
 	struct xfrm6_tunnel_spi *x6spi;
 	u32 spi;
 
-	write_lock_bh(&xfrm6_tunnel_spi_lock);
+	spin_lock_bh(&xfrm6_tunnel_spi_lock);
 	x6spi = __xfrm6_tunnel_spi_lookup(saddr);
 	if (x6spi) {
 		atomic_inc(&x6spi->refcnt);
 		spi = x6spi->spi;
 	} else
 		spi = __xfrm6_tunnel_alloc_spi(saddr);
-	write_unlock_bh(&xfrm6_tunnel_spi_lock);
+	spin_unlock_bh(&xfrm6_tunnel_spi_lock);
 
 	return htonl(spi);
 }
 
 EXPORT_SYMBOL(xfrm6_tunnel_alloc_spi);
 
+static void x6spi_destroy_rcu(struct rcu_head *head)
+{
+	kmem_cache_free(xfrm6_tunnel_spi_kmem,
+			container_of(head, struct xfrm6_tunnel_spi, rcu_head));
+}
+
 void xfrm6_tunnel_free_spi(xfrm_address_t *saddr)
 {
 	struct xfrm6_tunnel_spi *x6spi;
 	struct hlist_node *pos, *n;
 
-	write_lock_bh(&xfrm6_tunnel_spi_lock);
+	spin_lock_bh(&xfrm6_tunnel_spi_lock);
 
 	hlist_for_each_entry_safe(x6spi, pos, n,
 				  &xfrm6_tunnel_spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)],
@@ -229,14 +238,14 @@ void xfrm6_tunnel_free_spi(xfrm_address_t *saddr)
 	{
 		if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0) {
 			if (atomic_dec_and_test(&x6spi->refcnt)) {
-				hlist_del(&x6spi->list_byaddr);
-				hlist_del(&x6spi->list_byspi);
-				kmem_cache_free(xfrm6_tunnel_spi_kmem, x6spi);
+				hlist_del_rcu(&x6spi->list_byaddr);
+				hlist_del_rcu(&x6spi->list_byspi);
+				call_rcu(&x6spi->rcu_head, x6spi_destroy_rcu);
 				break;
 			}
 		}
 	}
-	write_unlock_bh(&xfrm6_tunnel_spi_lock);
+	spin_unlock_bh(&xfrm6_tunnel_spi_lock);
 }
 
 EXPORT_SYMBOL(xfrm6_tunnel_free_spi);

^ permalink raw reply related

* [PATCH 2/2 net-next-2.6] ipv6 sit: RCU conversion phase II
From: Eric Dumazet @ 2009-10-24  3:52 UTC (permalink / raw)
  To: David S. Miller; +Cc: Linux Netdev List, Yoshifuji Hideaki

SIT tunnels use one rwlock to protect their hash tables.

This locking scheme can be converted to RCU for free, since netdevice
already must wait for a RCU grace period at dismantle time.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
 net/ipv6/sit.c |   45 +++++++++++++++++++++++++++------------------
 1 files changed, 27 insertions(+), 18 deletions(-)

diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 8cdcc2a..b6b1626 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -77,8 +77,17 @@ struct sit_net {
 	struct net_device *fb_tunnel_dev;
 };
 
-static DEFINE_RWLOCK(ipip6_lock);
+/*
+ * Locking : hash tables are protected by RCU and a spinlock
+ */
+static DEFINE_SPINLOCK(ipip6_lock);
+
+#define for_each_ip_tunnel_rcu(start) \
+	for (t = rcu_dereference(start); t; t = rcu_dereference(t->next))
 
+/*
+ * Must be invoked with rcu_read_lock
+ */
 static struct ip_tunnel * ipip6_tunnel_lookup(struct net *net,
 		struct net_device *dev, __be32 remote, __be32 local)
 {
@@ -87,26 +96,26 @@ static struct ip_tunnel * ipip6_tunnel_lookup(struct net *net,
 	struct ip_tunnel *t;
 	struct sit_net *sitn = net_generic(net, sit_net_id);
 
-	for (t = sitn->tunnels_r_l[h0^h1]; t; t = t->next) {
+	for_each_ip_tunnel_rcu(sitn->tunnels_r_l[h0 ^ h1]) {
 		if (local == t->parms.iph.saddr &&
 		    remote == t->parms.iph.daddr &&
 		    (!dev || !t->parms.link || dev->iflink == t->parms.link) &&
 		    (t->dev->flags & IFF_UP))
 			return t;
 	}
-	for (t = sitn->tunnels_r[h0]; t; t = t->next) {
+	for_each_ip_tunnel_rcu(sitn->tunnels_r[h0]) {
 		if (remote == t->parms.iph.daddr &&
 		    (!dev || !t->parms.link || dev->iflink == t->parms.link) &&
 		    (t->dev->flags & IFF_UP))
 			return t;
 	}
-	for (t = sitn->tunnels_l[h1]; t; t = t->next) {
+	for_each_ip_tunnel_rcu(sitn->tunnels_l[h1]) {
 		if (local == t->parms.iph.saddr &&
 		    (!dev || !t->parms.link || dev->iflink == t->parms.link) &&
 		    (t->dev->flags & IFF_UP))
 			return t;
 	}
-	t = sitn->tunnels_wc[0];
+	t = rcu_dereference(sitn->tunnels_wc[0]);
 	if ((t != NULL) && (t->dev->flags & IFF_UP))
 		return t;
 	return NULL;
@@ -143,9 +152,9 @@ static void ipip6_tunnel_unlink(struct sit_net *sitn, struct ip_tunnel *t)
 
 	for (tp = ipip6_bucket(sitn, t); *tp; tp = &(*tp)->next) {
 		if (t == *tp) {
-			write_lock_bh(&ipip6_lock);
+			spin_lock_bh(&ipip6_lock);
 			*tp = t->next;
-			write_unlock_bh(&ipip6_lock);
+			spin_unlock_bh(&ipip6_lock);
 			break;
 		}
 	}
@@ -155,10 +164,10 @@ static void ipip6_tunnel_link(struct sit_net *sitn, struct ip_tunnel *t)
 {
 	struct ip_tunnel **tp = ipip6_bucket(sitn, t);
 
+	spin_lock_bh(&ipip6_lock);
 	t->next = *tp;
-	write_lock_bh(&ipip6_lock);
-	*tp = t;
-	write_unlock_bh(&ipip6_lock);
+	rcu_assign_pointer(*tp, t);
+	spin_unlock_bh(&ipip6_lock);
 }
 
 static void ipip6_tunnel_clone_6rd(struct net_device *dev, struct sit_net *sitn)
@@ -447,9 +456,9 @@ static void ipip6_tunnel_uninit(struct net_device *dev)
 	struct sit_net *sitn = net_generic(net, sit_net_id);
 
 	if (dev == sitn->fb_tunnel_dev) {
-		write_lock_bh(&ipip6_lock);
+		spin_lock_bh(&ipip6_lock);
 		sitn->tunnels_wc[0] = NULL;
-		write_unlock_bh(&ipip6_lock);
+		spin_unlock_bh(&ipip6_lock);
 		dev_put(dev);
 	} else {
 		ipip6_tunnel_unlink(sitn, netdev_priv(dev));
@@ -502,7 +511,7 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
 
 	err = -ENOENT;
 
-	read_lock(&ipip6_lock);
+	rcu_read_lock();
 	t = ipip6_tunnel_lookup(dev_net(skb->dev),
 				skb->dev,
 				iph->daddr,
@@ -520,7 +529,7 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
 		t->err_count = 1;
 	t->err_time = jiffies;
 out:
-	read_unlock(&ipip6_lock);
+	rcu_read_unlock();
 	return err;
 }
 
@@ -540,7 +549,7 @@ static int ipip6_rcv(struct sk_buff *skb)
 
 	iph = ip_hdr(skb);
 
-	read_lock(&ipip6_lock);
+	rcu_read_lock();
 	tunnel = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev,
 				     iph->saddr, iph->daddr);
 	if (tunnel != NULL) {
@@ -554,7 +563,7 @@ static int ipip6_rcv(struct sk_buff *skb)
 		if ((tunnel->dev->priv_flags & IFF_ISATAP) &&
 		    !isatap_chksrc(skb, iph, tunnel)) {
 			tunnel->dev->stats.rx_errors++;
-			read_unlock(&ipip6_lock);
+			rcu_read_unlock();
 			kfree_skb(skb);
 			return 0;
 		}
@@ -565,12 +574,12 @@ static int ipip6_rcv(struct sk_buff *skb)
 		nf_reset(skb);
 		ipip6_ecn_decapsulate(iph, skb);
 		netif_rx(skb);
-		read_unlock(&ipip6_lock);
+		rcu_read_unlock();
 		return 0;
 	}
 
 	icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
-	read_unlock(&ipip6_lock);
+	rcu_read_unlock();
 out:
 	kfree_skb(skb);
 	return 0;

^ permalink raw reply related

* [PATCH 1/2 net-next-2.6] ipv6 sit: RCU conversion phase I
From: Eric Dumazet @ 2009-10-24  3:51 UTC (permalink / raw)
  To: David S. Miller; +Cc: Linux Netdev List, Yoshifuji Hideaki

SIT tunnels use one rwlock to protect their prl entries.

This first patch adds RCU locking for prl management,
with standard call_rcu() calls.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
 include/net/ipip.h |    1
 net/ipv6/sit.c     |   73 +++++++++++++++++++++++++++++--------------
 2 files changed, 51 insertions(+), 23 deletions(-)

diff --git a/include/net/ipip.h b/include/net/ipip.h
index 86f1c8b..290effb 100644
--- a/include/net/ipip.h
+++ b/include/net/ipip.h
@@ -45,6 +45,7 @@ struct ip_tunnel_prl_entry
 	struct ip_tunnel_prl_entry	*next;
 	__be32				addr;
 	u16				flags;
+	struct rcu_head			rcu_head;
 };
 
 #define IPTUNNEL_XMIT() do {						\
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 510d31f..8cdcc2a 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -240,15 +240,22 @@ failed:
 	return NULL;
 }
 
+static DEFINE_SPINLOCK(ipip6_prl_lock);
+
+#define for_each_prl_rcu(start)			\
+	for (prl = rcu_dereference(start);	\
+	     prl;				\
+	     prl = rcu_dereference(prl->next))
+
 static struct ip_tunnel_prl_entry *
 __ipip6_tunnel_locate_prl(struct ip_tunnel *t, __be32 addr)
 {
-	struct ip_tunnel_prl_entry *p = (struct ip_tunnel_prl_entry *)NULL;
+	struct ip_tunnel_prl_entry *prl;
 
-	for (p = t->prl; p; p = p->next)
-		if (p->addr == addr)
+	for_each_prl_rcu(t->prl)
+		if (prl->addr == addr)
 			break;
-	return p;
+	return prl;
 
 }
 
@@ -273,7 +280,7 @@ static int ipip6_tunnel_get_prl(struct ip_tunnel *t,
 		kcalloc(cmax, sizeof(*kp), GFP_KERNEL) :
 		NULL;
 
-	read_lock(&ipip6_lock);
+	rcu_read_lock();
 
 	ca = t->prl_count < cmax ? t->prl_count : cmax;
 
@@ -291,7 +298,7 @@ static int ipip6_tunnel_get_prl(struct ip_tunnel *t,
 	}
 
 	c = 0;
-	for (prl = t->prl; prl; prl = prl->next) {
+	for_each_prl_rcu(t->prl) {
 		if (c >= cmax)
 			break;
 		if (kprl.addr != htonl(INADDR_ANY) && prl->addr != kprl.addr)
@@ -303,7 +310,7 @@ static int ipip6_tunnel_get_prl(struct ip_tunnel *t,
 			break;
 	}
 out:
-	read_unlock(&ipip6_lock);
+	rcu_read_unlock();
 
 	len = sizeof(*kp) * c;
 	ret = 0;
@@ -324,12 +331,14 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg)
 	if (a->addr == htonl(INADDR_ANY))
 		return -EINVAL;
 
-	write_lock(&ipip6_lock);
+	spin_lock(&ipip6_prl_lock);
 
 	for (p = t->prl; p; p = p->next) {
 		if (p->addr == a->addr) {
-			if (chg)
-				goto update;
+			if (chg) {
+				p->flags = a->flags;
+				goto out;
+			}
 			err = -EEXIST;
 			goto out;
 		}
@@ -346,46 +355,63 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg)
 		goto out;
 	}
 
+	INIT_RCU_HEAD(&p->rcu_head);
 	p->next = t->prl;
-	t->prl = p;
-	t->prl_count++;
-update:
 	p->addr = a->addr;
 	p->flags = a->flags;
+	t->prl_count++;
+	rcu_assign_pointer(t->prl, p);
 out:
-	write_unlock(&ipip6_lock);
+	spin_unlock(&ipip6_prl_lock);
 	return err;
 }
 
+static void prl_entry_destroy_rcu(struct rcu_head *head)
+{
+	kfree(container_of(head, struct ip_tunnel_prl_entry, rcu_head));
+}
+
+static void prl_list_destroy_rcu(struct rcu_head *head)
+{
+	struct ip_tunnel_prl_entry *p, *n;
+
+	p = container_of(head, struct ip_tunnel_prl_entry, rcu_head);
+	do {
+		n = p->next;
+		kfree(p);
+		p = n;
+	} while (p);
+}
+
 static int
 ipip6_tunnel_del_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a)
 {
 	struct ip_tunnel_prl_entry *x, **p;
 	int err = 0;
 
-	write_lock(&ipip6_lock);
+	spin_lock(&ipip6_prl_lock);
 
 	if (a && a->addr != htonl(INADDR_ANY)) {
 		for (p = &t->prl; *p; p = &(*p)->next) {
 			if ((*p)->addr == a->addr) {
 				x = *p;
 				*p = x->next;
-				kfree(x);
+				call_rcu(&x->rcu_head, prl_entry_destroy_rcu);
 				t->prl_count--;
 				goto out;
 			}
 		}
 		err = -ENXIO;
 	} else {
-		while (t->prl) {
+		if (t->prl) {
+			t->prl_count = 0;
 			x = t->prl;
-			t->prl = t->prl->next;
-			kfree(x);
-			t->prl_count--;
+			call_rcu(&x->rcu_head, prl_list_destroy_rcu);
+			t->prl = NULL;
 		}
 	}
 out:
-	write_unlock(&ipip6_lock);
+	spin_unlock(&ipip6_prl_lock);
 	return err;
 }
 
@@ -395,7 +421,7 @@ isatap_chksrc(struct sk_buff *skb, struct iphdr *iph, struct ip_tunnel *t)
 	struct ip_tunnel_prl_entry *p;
 	int ok = 1;
 
-	read_lock(&ipip6_lock);
+	rcu_read_lock();
 	p = __ipip6_tunnel_locate_prl(t, iph->saddr);
 	if (p) {
 		if (p->flags & PRL_DEFAULT)
@@ -411,7 +437,7 @@ isatap_chksrc(struct sk_buff *skb, struct iphdr *iph, struct ip_tunnel *t)
 		else
 			ok = 0;
 	}
-	read_unlock(&ipip6_lock);
+	rcu_read_unlock();
 	return ok;
 }
 
@@ -1192,6 +1218,7 @@ static void __exit sit_cleanup(void)
 	xfrm4_tunnel_deregister(&sit_handler, AF_INET6);
 
 	unregister_pernet_gen_device(sit_net_id, &sit_net_ops);
+	rcu_barrier(); /* Wait for completion of call_rcu()'s */
 }
 
 static int __init sit_init(void)

^ permalink raw reply related

* Re: Irq architecture for multi-core network driver.
From: David Miller @ 2009-10-24  3:19 UTC (permalink / raw)
  To: jesse.brandeburg
  Cc: ebiederm, ddaney, cfriesen, netdev, linux-kernel, linux-mips
In-Reply-To: <4807377b0910231028g60b479cfycdbf3f4e25384c58@mail.gmail.com>

From: Jesse Brandeburg <jesse.brandeburg@gmail.com>
Date: Fri, 23 Oct 2009 10:28:10 -0700

> Yes, I know Arjan and others will say you should always run
> irqbalance, but some people don't and some distros don't ship it
> enabled by default (or their version doesn't work for one reason or
> another)  The question is should the kernel work better by default
> *without* irqbalance loaded, or does it not matter?

I think requiring irqbalanced for optimal behavior is more
than reasonable.

And since we explicitly took that policy logic out of the
kernel it makes absolutely no sense to put it back there.

It's policy, and policy is (largely) userspace.

^ permalink raw reply

* Re: [Patch] sctp: remove deprecated SCTP_GET_*_OLD stuffs
From: Cong Wang @ 2009-10-24  2:41 UTC (permalink / raw)
  To: Vlad Yasevich; +Cc: Sam Ravnborg, linux-kernel, netdev, akpm
In-Reply-To: <4AE1D2AA.8060200@hp.com>

Vlad Yasevich wrote:
> 
> Sam Ravnborg wrote:
>> On Thu, Oct 22, 2009 at 04:53:30PM -0400, Vlad Yasevich wrote:
>>>> diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h
>>>> index be2334a..0991f1b 100644
>>>> --- a/include/net/sctp/user.h
>>>> +++ b/include/net/sctp/user.h
>>>> @@ -131,14 +131,6 @@ enum sctp_optname {
>>>>  #define SCTP_SOCKOPT_BINDX_REM	SCTP_SOCKOPT_BINDX_REM
>>>>  	SCTP_SOCKOPT_PEELOFF, 	/* peel off association. */
>>>>  #define SCTP_SOCKOPT_PEELOFF	SCTP_SOCKOPT_PEELOFF
>>>> -	SCTP_GET_PEER_ADDRS_NUM_OLD, 	/* Get number of peer addresss. */
>>>> -#define SCTP_GET_PEER_ADDRS_NUM_OLD	SCTP_GET_PEER_ADDRS_NUM_OLD
>>>> -	SCTP_GET_PEER_ADDRS_OLD, 	/* Get all peer addresss. */
>>>> -#define SCTP_GET_PEER_ADDRS_OLD	SCTP_GET_PEER_ADDRS_OLD
>>>> -	SCTP_GET_LOCAL_ADDRS_NUM_OLD, 	/* Get number of local addresss. */
>>>> -#define SCTP_GET_LOCAL_ADDRS_NUM_OLD	SCTP_GET_LOCAL_ADDRS_NUM_OLD
>>>> -	SCTP_GET_LOCAL_ADDRS_OLD, 	/* Get all local addresss. */
>>>> -#define SCTP_GET_LOCAL_ADDRS_OLD	SCTP_GET_LOCAL_ADDRS_OLD
>>>>  	SCTP_SOCKOPT_CONNECTX_OLD, /* CONNECTX old requests. */
>>> After running the regression suite against this patch I find that we can't
>>> remove the enum values.  Removing the enums changes the value for the remainder
>>> of the definitions and breaks binary compatibility for applications that use
>>> those trailing options.
>>>
>>> You should be ok with removing the #defines and actual code that uses them,
>>> but not the enums.  You can even rename the enums, but we must preserve
>>> numeric ordering.
>> If we really depend on the actual value of an enum as in this case,
>> then e should assign them direct to better document this.
>>
>> 	Sam
>>
> 
> I agree.  I have a patch that converts the enum to just a #define section that
> I'll apply on top of this removal patch and document the deletion.

Hi, Vlad.

I was busy, sorry for joining late. Thanks for doing this!

^ permalink raw reply

* Re: [patch next 3/4] netxen: fix bonding support
From: Eric W. Biederman @ 2009-10-24  2:13 UTC (permalink / raw)
  To: Dhananjay Phadke; +Cc: netdev@vger.kernel.org
In-Reply-To: <7608421F3572AB4292BB2532AE89D5658B0B6E4F72@AVEXMB1.qlogic.org>

Dhananjay Phadke <dhananjay.phadke@qlogic.com> writes:

> Yes, this was a bug until recent times.
>
> It should be fixed in 2.6.32 development cycle by this commit -
> db4cfd8a6149e778befb2ff6e6f91cdc6394cbe6 ("netxen: handle firmware load errors").
>
> This added a check for adapter->is_up before touching txq lock.

Yes.  That should prevent the null pointer deference.  Will it also
allow setting the mac address when the NIC is down?

Eric

^ permalink raw reply

* Re: [PATCH 2/5] page allocator: Do not allow interrupts to use ALLOC_HARDER
From: Christoph Lameter @ 2009-10-24  2:03 UTC (permalink / raw)
  To: Mel Gorman
  Cc: Stephan von Krawczynski, Frans Pop, Jiri Kosina, Sven Geggus,
	Karol Lewandowski, Tobias Oetiker, Rafael J. Wysocki,
	David Miller, Reinette Chatre, Kalle Valo, David Rientjes,
	KOSAKI Motohiro, Mohamed Abbas, Jens Axboe, John W. Linville,
	Pekka Enberg, Bartlomiej Zolnierkiewicz, Greg Kroah-Hartman,
	Kernel Testers List, netdev, linux-kernel
In-Reply-To: <20091022163752.GU11778@csn.ul.ie>

There are now rt dependencies in the page allocator that screw things up?

And an rt flag causes the page allocator to try harder meaning it adds
latency.

?


--
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/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ 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