* [PATCH 09/33] mm: system wide ALLOC_NO_WATERMARK
From: Peter Zijlstra @ 2007-10-30 16:04 UTC (permalink / raw)
To: Linus Torvalds, Andrew Morton, linux-kernel, linux-mm, netdev,
trond.myklebust
Cc: Peter Zijlstra
In-Reply-To: <20071030160401.296770000@chello.nl>
[-- Attachment #1: global-ALLOC_NO_WATERMARKS.patch --]
[-- Type: text/plain, Size: 852 bytes --]
Change ALLOC_NO_WATERMARK page allocation such that the reserves are system
wide - which they are per setup_per_zone_pages_min(), when we scrape the
barrel, do it properly.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
mm/page_alloc.c | 6 ++++++
1 file changed, 6 insertions(+)
Index: linux-2.6/mm/page_alloc.c
===================================================================
--- linux-2.6.orig/mm/page_alloc.c
+++ linux-2.6/mm/page_alloc.c
@@ -1638,6 +1638,12 @@ restart:
rebalance:
if (alloc_flags & ALLOC_NO_WATERMARKS) {
nofail_alloc:
+ /*
+ * break out of mempolicy boundaries
+ */
+ zonelist = NODE_DATA(numa_node_id())->node_zonelists +
+ gfp_zone(gfp_mask);
+
/* go through the zonelist yet again, ignoring mins */
page = get_page_from_freelist(gfp_mask, order, zonelist,
ALLOC_NO_WATERMARKS);
--
^ permalink raw reply
* [PATCH 07/33] mm: serialize access to min_free_kbytes
From: Peter Zijlstra @ 2007-10-30 16:04 UTC (permalink / raw)
To: Linus Torvalds, Andrew Morton, linux-kernel, linux-mm, netdev,
trond.myklebust
Cc: Peter Zijlstra
In-Reply-To: <20071030160401.296770000@chello.nl>
[-- Attachment #1: mm-setup_per_zone_pages_min.patch --]
[-- Type: text/plain, Size: 1835 bytes --]
There is a small race between the procfs caller and the memory hotplug caller
of setup_per_zone_pages_min(). Not a big deal, but the next patch will add yet
another caller. Time to close the gap.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
mm/page_alloc.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
Index: linux-2.6/mm/page_alloc.c
===================================================================
--- linux-2.6.orig/mm/page_alloc.c
+++ linux-2.6/mm/page_alloc.c
@@ -116,6 +116,7 @@ static char * const zone_names[MAX_NR_ZO
"Movable",
};
+static DEFINE_SPINLOCK(min_free_lock);
int min_free_kbytes = 1024;
unsigned long __meminitdata nr_kernel_pages;
@@ -4162,12 +4163,12 @@ static void setup_per_zone_lowmem_reserv
}
/**
- * setup_per_zone_pages_min - called when min_free_kbytes changes.
+ * __setup_per_zone_pages_min - called when min_free_kbytes changes.
*
* Ensures that the pages_{min,low,high} values for each zone are set correctly
* with respect to min_free_kbytes.
*/
-void setup_per_zone_pages_min(void)
+static void __setup_per_zone_pages_min(void)
{
unsigned long pages_min = min_free_kbytes >> (PAGE_SHIFT - 10);
unsigned long lowmem_pages = 0;
@@ -4222,6 +4223,15 @@ void setup_per_zone_pages_min(void)
calculate_totalreserve_pages();
}
+void setup_per_zone_pages_min(void)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&min_free_lock, flags);
+ __setup_per_zone_pages_min();
+ spin_unlock_irqrestore(&min_free_lock, flags);
+}
+
/*
* Initialise min_free_kbytes.
*
@@ -4257,7 +4267,7 @@ static int __init init_per_zone_pages_mi
min_free_kbytes = 128;
if (min_free_kbytes > 65536)
min_free_kbytes = 65536;
- setup_per_zone_pages_min();
+ __setup_per_zone_pages_min();
setup_per_zone_lowmem_reserve();
return 0;
}
--
^ permalink raw reply
* [PATCH 06/33] mm: allow PF_MEMALLOC from softirq context
From: Peter Zijlstra @ 2007-10-30 16:04 UTC (permalink / raw)
To: Linus Torvalds, Andrew Morton, linux-kernel, linux-mm, netdev,
trond.myklebust
Cc: Peter Zijlstra
In-Reply-To: <20071030160401.296770000@chello.nl>
[-- Attachment #1: mm-PF_MEMALLOC-softirq.patch --]
[-- Type: text/plain, Size: 2199 bytes --]
Allow PF_MEMALLOC to be set in softirq context. When running softirqs from
a borrowed context save current->flags, ksoftirqd will have its own
task_struct.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
include/linux/sched.h | 4 ++++
kernel/softirq.c | 3 +++
mm/page_alloc.c | 7 ++++---
3 files changed, 11 insertions(+), 3 deletions(-)
Index: linux-2.6/mm/page_alloc.c
===================================================================
--- linux-2.6.orig/mm/page_alloc.c
+++ linux-2.6/mm/page_alloc.c
@@ -1557,9 +1557,10 @@ int gfp_to_alloc_flags(gfp_t gfp_mask)
alloc_flags |= ALLOC_HARDER;
if (likely(!(gfp_mask & __GFP_NOMEMALLOC))) {
- if (!in_interrupt() &&
- ((p->flags & PF_MEMALLOC) ||
- unlikely(test_thread_flag(TIF_MEMDIE))))
+ if (!in_irq() && (p->flags & PF_MEMALLOC))
+ alloc_flags |= ALLOC_NO_WATERMARKS;
+ else if (!in_interrupt() &&
+ unlikely(test_thread_flag(TIF_MEMDIE)))
alloc_flags |= ALLOC_NO_WATERMARKS;
}
Index: linux-2.6/kernel/softirq.c
===================================================================
--- linux-2.6.orig/kernel/softirq.c
+++ linux-2.6/kernel/softirq.c
@@ -211,6 +211,8 @@ asmlinkage void __do_softirq(void)
__u32 pending;
int max_restart = MAX_SOFTIRQ_RESTART;
int cpu;
+ unsigned long pflags = current->flags;
+ current->flags &= ~PF_MEMALLOC;
pending = local_softirq_pending();
account_system_vtime(current);
@@ -249,6 +251,7 @@ restart:
account_system_vtime(current);
_local_bh_enable();
+ tsk_restore_flags(current, pflags, PF_MEMALLOC);
}
#ifndef __ARCH_HAS_DO_SOFTIRQ
Index: linux-2.6/include/linux/sched.h
===================================================================
--- linux-2.6.orig/include/linux/sched.h
+++ linux-2.6/include/linux/sched.h
@@ -1389,6 +1389,10 @@ static inline void put_task_struct(struc
#define tsk_used_math(p) ((p)->flags & PF_USED_MATH)
#define used_math() tsk_used_math(current)
+#define tsk_restore_flags(p, pflags, mask) \
+ do { (p)->flags &= ~(mask); \
+ (p)->flags |= ((pflags) & (mask)); } while (0)
+
#ifdef CONFIG_SMP
extern int set_cpus_allowed(struct task_struct *p, cpumask_t new_mask);
#else
--
^ permalink raw reply
* [PATCH 04/33] mm: allow mempool to fall back to memalloc reserves
From: Peter Zijlstra @ 2007-10-30 16:04 UTC (permalink / raw)
To: Linus Torvalds, Andrew Morton, linux-kernel, linux-mm, netdev,
trond.myklebust
Cc: Peter Zijlstra
In-Reply-To: <20071030160401.296770000@chello.nl>
[-- Attachment #1: mm-mempool_fixup.patch --]
[-- Type: text/plain, Size: 1322 bytes --]
Allow the mempool to use the memalloc reserves when all else fails and
the allocation context would otherwise allow it.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
mm/mempool.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
Index: linux-2.6/mm/mempool.c
===================================================================
--- linux-2.6.orig/mm/mempool.c
+++ linux-2.6/mm/mempool.c
@@ -14,6 +14,7 @@
#include <linux/mempool.h>
#include <linux/blkdev.h>
#include <linux/writeback.h>
+#include "internal.h"
static void add_element(mempool_t *pool, void *element)
{
@@ -204,7 +205,7 @@ void * mempool_alloc(mempool_t *pool, gf
void *element;
unsigned long flags;
wait_queue_t wait;
- gfp_t gfp_temp;
+ gfp_t gfp_temp, gfp_orig = gfp_mask;
might_sleep_if(gfp_mask & __GFP_WAIT);
@@ -228,6 +229,15 @@ repeat_alloc:
}
spin_unlock_irqrestore(&pool->lock, flags);
+ /* if we really had right to the emergency reserves try those */
+ if (gfp_to_alloc_flags(gfp_orig) & ALLOC_NO_WATERMARKS) {
+ if (gfp_temp & __GFP_NOMEMALLOC) {
+ gfp_temp &= ~(__GFP_NOMEMALLOC|__GFP_NOWARN);
+ goto repeat_alloc;
+ } else
+ gfp_temp |= __GFP_NOMEMALLOC|__GFP_NOWARN;
+ }
+
/* We must not sleep in the GFP_ATOMIC case */
if (!(gfp_mask & __GFP_WAIT))
return NULL;
--
^ permalink raw reply
* [PATCH 00/33] Swap over NFS -v14
From: Peter Zijlstra @ 2007-10-30 16:04 UTC (permalink / raw)
To: Linus Torvalds, Andrew Morton, linux-kernel, linux-mm, netdev,
trond.myklebust
Cc: Peter Zijlstra
Hi,
Another posting of the full swap over NFS series.
[ I tried just posting the first part last time around, but
that just gets more confusion by lack of a general picture ]
[ patches against 2.6.23-mm1, also to be found online at:
http://programming.kicks-ass.net/kernel-patches/vm_deadlock/v2.6.23-mm1/ ]
The patch-set can be split in roughtly 5 parts, for each of which I shall give
a description.
Part 1, patches 1-12
The problem with swap over network is the generic swap problem: needing memory
to free memory. Normally this is solved using mempools, as can be seen in the
BIO layer.
Swap over network has the problem that the network subsystem does not use fixed
sized allocations, but heavily relies on kmalloc(). This makes mempools
unusable.
This first part provides a generic reserve framework.
Care is taken to only affect the slow paths - when we're low on memory.
Caveats: it is currently SLUB only.
1 - mm: gfp_to_alloc_flags()
2 - mm: tag reseve pages
3 - mm: slub: add knowledge of reserve pages
4 - mm: allow mempool to fall back to memalloc reserves
5 - mm: kmem_estimate_pages()
6 - mm: allow PF_MEMALLOC from softirq context
7 - mm: serialize access to min_free_kbytes
8 - mm: emergency pool
9 - mm: system wide ALLOC_NO_WATERMARK
10 - mm: __GFP_MEMALLOC
11 - mm: memory reserve management
12 - selinux: tag avc cache alloc as non-critical
Part 2, patches 13-15
Provide some generic network infrastructure needed later on.
13 - net: wrap sk->sk_backlog_rcv()
14 - net: packet split receive api
15 - net: sk_allocation() - concentrate socket related allocations
Part 3, patches 16-23
Now that we have a generic memory reserve system, use it on the network stack.
The thing that makes this interesting is that, contrary to BIO, both the
transmit and receive path require memory allocations.
That is, in the BIO layer write back completion is usually just an ISR flipping
a bit and waking stuff up. A network write back completion involved receiving
packets, which when there is no memory, is rather hard. And even when there is
memory there is no guarantee that the required packet comes in in the window
that that memory buys us.
The solution to this problem is found in the fact that network is to be assumed
lossy. Even now, when there is no memory to receive packets the network card
will have to discard packets. What we do is move this into the network stack.
So we reserve a little pool to act as a receive buffer, this allows us to
inspect packets before tossing them. This way, we can filter out those packets
that ensure progress (writeback completion) and disregard the others (as would
have happened anyway). [ NOTE: this is a stable mode of operation with limited
memory usage, exactly the kind of thing we need ]
Again, care is taken to keep much of the overhead of this to only affect the
slow path. Only packets allocated from the reserves will suffer the extra
atomic overhead needed for accounting.
16 - netvm: network reserve infrastructure
17 - sysctl: propagate conv errors
18 - netvm: INET reserves.
19 - netvm: hook skb allocation to reserves
20 - netvm: filter emergency skbs.
21 - netvm: prevent a TCP specific deadlock
22 - netfilter: NF_QUEUE vs emergency skbs
23 - netvm: skb processing
Part 4, patches 24-26
Generic vm infrastructure to handle swapping to a filesystem instead of a block
device. The approach here has been questioned, people would like to see a less
invasive approach.
One suggestion is to create and use a_ops->swap_{in,out}().
24 - mm: prepare swap entry methods for use in page methods
25 - mm: add support for non block device backed swap files
26 - mm: methods for teaching filesystems about PG_swapcache pages
Part 5, patches 27-33
Finally, convert NFS to make use of the new network and vm infrastructure to
provide swap over NFS.
27 - nfs: remove mempools
28 - nfs: teach the NFS client how to treat PG_swapcache pages
29 - nfs: disable data cache revalidation for swapfiles
30 - nfs: swap vs nfs_writepage
31 - nfs: enable swap on NFS
32 - nfs: fix various memory recursions possible with swap over NFS.
33 - nfs: do not warn on radix tree node allocation failures
^ permalink raw reply
* Re: [PATCH 1/2] Convert /proc/net/ipv6_route to seq_file interface
From: Patrick McHardy @ 2007-10-30 15:37 UTC (permalink / raw)
To: Alexey Dobriyan; +Cc: Stephen Hemminger, netdev
In-Reply-To: <20071030083043.47f5def3@freepuppy.rosehill>
Stephen Hemminger wrote:
> On Tue, 30 Oct 2007 16:11:47 +0300
> Alexey Dobriyan <adobriyan@sw.ru> wrote:
>>
>> +static const struct file_operations ipv6_route_proc_fops = {
>> + .open = ipv6_route_open,
>> + .read = seq_read,
>> + .llseek = seq_lseek,
>> + .release = single_release,
>> +};
>> +
>
> This needs
> .owner = THIS_MODULE,
Your ip_queue conversion patch was also missing this, I've
fixed it up.
^ permalink raw reply
* Re: [PATCH] nf_nat_h323.c unneeded rcu_dereference() calls
From: Paul E. McKenney @ 2007-10-30 15:37 UTC (permalink / raw)
To: Patrick McHardy; +Cc: linux-kernel, netdev, rusty, zhaojingmin, davem
In-Reply-To: <47273A5C.7040909@trash.net>
On Tue, Oct 30, 2007 at 03:06:20PM +0100, Patrick McHardy wrote:
> Paul E. McKenney wrote:
> >Hello!
> >
> >While reviewing rcu_dereference() uses, I came across a number of cases
> >where I couldn't see how the rcu_dereference() helped. One class of
> >cases is where the variable is never subsequently dereferenced, so that
> >patches like the following one would be appropriate.
> >
> >So, what am I missing here?
>
> Nothing, it was mainly intended as documentation that the hooks are
> protected by RCU. I agree that its probably more confusing this way
> since we're not even in a rcu_read_lock protected section.
>
> I've queued a patch to remove them all.
Thank you!!!
Thanx, Paul
^ permalink raw reply
* Re: dn_route.c momentarily exiting RCU read-side critical section
From: Paul E. McKenney @ 2007-10-30 15:12 UTC (permalink / raw)
To: David Miller; +Cc: linux-kernel, netdev, SteveW, dipankar
In-Reply-To: <20071030.011036.43329108.davem@davemloft.net>
On Tue, Oct 30, 2007 at 01:10:36AM -0700, David Miller wrote:
> From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
> Date: Mon, 29 Oct 2007 14:15:40 -0700
>
> > net/decnet/dn_route.c in dn_rt_cache_get_next() is as follows:
> >
> > static struct dn_route *dn_rt_cache_get_next(struct seq_file *seq, struct dn_route *rt)
> > {
> > struct dn_rt_cache_iter_state *s = rcu_dereference(seq->private);
> >
> > rt = rt->u.dst.dn_next;
> > while(!rt) {
> > rcu_read_unlock_bh();
> > if (--s->bucket < 0)
> > break;
> >
> > ... But what happens if seq->private is freed up right here?
> > ... Or what prevents this from happening?
> ...
> > Similar code is in rt_cache_get_next().
> >
> > So, what am I missing here?
>
> seq->private is allocated on file open (here via seq_open_private()),
> and freed up on file close (via seq_release_private).
>
> So it cannot be freed up in the middle of an iteration.
Thank you for the info!!!
OK, for my next stupid question: why is the rcu_dereference(seq->private)
required, as opposed to simply seq->private?
Thanx, Paul
^ permalink raw reply
* Re: [PATCH 1/2] Convert /proc/net/ipv6_route to seq_file interface
From: Stephen Hemminger @ 2007-10-30 15:30 UTC (permalink / raw)
To: Alexey Dobriyan; +Cc: netdev
In-Reply-To: <20071030131147.GA6210@localhost.sw.ru>
On Tue, 30 Oct 2007 16:11:47 +0300
Alexey Dobriyan <adobriyan@sw.ru> wrote:
>
> +static const struct file_operations ipv6_route_proc_fops = {
> + .open = ipv6_route_open,
> + .read = seq_read,
> + .llseek = seq_lseek,
> + .release = single_release,
> +};
> +
This needs
.owner = THIS_MODULE,
>
> static int rt6_stats_seq_show(struct seq_file *seq, void *v)
> {
> seq_printf(seq, "%04x %04x %04x %04x %04x %04x %04x\n",
> @@ -2499,9 +2477,11 @@ void __init ip6_route_init(void)
>
> fib6_init();
> #ifdef CONFIG_PROC_FS
> - p = proc_net_create(&init_net, "ipv6_route", 0, rt6_proc_info);
> - if (p)
> + p = create_proc_entry("ipv6_route", 0, init_net.proc_net);
> + if (p) {
> p->owner = THIS_MODULE;
> + p->proc_fops = &ipv6_route_proc_fops;
> + }
>
> proc_net_fops_create(&init_net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops);
> #endif
>
Use proc_net_fops_create()
proc_net_fops_create(&init_net, "ipv6_route", S_IRUGO, &ipv6_route_proc_fops)
You can get rid of #ifdef since proc_net_fops_create stub does correct thing
if PROC_FS is not configured.
--
Stephen Hemminger <shemminger@linux-foundation.org>
^ permalink raw reply
* Re: [PATCH 1/2] [CRYPTO] tcrypt: Move sg_init_table out of timing loops
From: Herbert Xu @ 2007-10-30 14:18 UTC (permalink / raw)
To: Jens Axboe
Cc: David S. Miller, Linux Kernel Mailing List,
Linux Crypto Mailing List, netdev
In-Reply-To: <20071030055056.GG7499@kernel.dk>
On Tue, Oct 30, 2007 at 06:50:58AM +0100, Jens Axboe wrote:
>
> How so? The reason you changed it to sg_init_table() + sg_set_buf() is
> exactly because sg_init_one() didn't properly init the entry (as they
> name promised).
For one of the cases yes but the other one repeatedly calls
sg_init_one on the same sg entry while we really only need
to initialise it once and call sg_set_buf afterwards.
Normally this is irrelevant but the loops in question are
trying to estimate the speed of the algorithms so it's good
to exclude as much noise from them as possible.
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <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 1/2] [CRYPTO] tcrypt: Move sg_init_table out of timing loops
From: Jens Axboe @ 2007-10-30 14:17 UTC (permalink / raw)
To: Herbert Xu
Cc: David S. Miller, Linux Kernel Mailing List,
Linux Crypto Mailing List, netdev
In-Reply-To: <20071030141820.GA16501@gondor.apana.org.au>
On Tue, Oct 30 2007, Herbert Xu wrote:
> On Tue, Oct 30, 2007 at 06:50:58AM +0100, Jens Axboe wrote:
> >
> > How so? The reason you changed it to sg_init_table() + sg_set_buf() is
> > exactly because sg_init_one() didn't properly init the entry (as they
> > name promised).
>
> For one of the cases yes but the other one repeatedly calls
> sg_init_one on the same sg entry while we really only need
> to initialise it once and call sg_set_buf afterwards.
>
> Normally this is irrelevant but the loops in question are
> trying to estimate the speed of the algorithms so it's good
> to exclude as much noise from them as possible.
Ah OK, I was referring to the replacement mentioned above.
--
Jens Axboe
^ permalink raw reply
* Re: [PATCH] nf_nat_h323.c unneeded rcu_dereference() calls
From: Patrick McHardy @ 2007-10-30 14:06 UTC (permalink / raw)
To: paulmck; +Cc: linux-kernel, netdev, rusty, zhaojingmin, davem
In-Reply-To: <20071029210618.GA4200@linux.vnet.ibm.com>
Paul E. McKenney wrote:
> Hello!
>
> While reviewing rcu_dereference() uses, I came across a number of cases
> where I couldn't see how the rcu_dereference() helped. One class of
> cases is where the variable is never subsequently dereferenced, so that
> patches like the following one would be appropriate.
>
> So, what am I missing here?
Nothing, it was mainly intended as documentation that the hooks are
protected by RCU. I agree that its probably more confusing this way
since we're not even in a rcu_read_lock protected section.
I've queued a patch to remove them all.
^ permalink raw reply
* Re: Oops in 2.6.21-rc4, 2.6.23
From: Jarek Poplawski @ 2007-10-30 14:11 UTC (permalink / raw)
To: David Miller; +Cc: darko.koruga, netdev
In-Reply-To: <20071029.014147.56411400.davem@davemloft.net>
On Mon, Oct 29, 2007 at 01:41:47AM -0700, David Miller wrote:
...
> Actually, this was caused by a real bug in the SKB_WITH_OVERHEAD macro
> definition, which Herbert Xu quickly spotted and fixed.
>
> Which "I hope you've found this by yourself by now".
>
...Btw, of course you have to be right, and I should find this in max.
12 days yet, if I'm as smart as I hope. But as for now, I really can't
see any meaningful difference between this "buggy" SKB_WITH_OVERHEAD
version and 'generic' 2.6.20.
There is also a tiny doubt, how this all could influence 2.6.21-rc4,
which seems to be 'generic' here as well. I guess it has to be some
git issue... the more so, as I can't see there this other (bisected)
patch as well?! Then, of course, this could be my sight issue - but
then these 12 days are definitely not enough...
Cheers,
Jarek P.
^ permalink raw reply
* Re: Configuring the same IP on multiple addresses
From: Vlad Yasevich @ 2007-10-30 13:47 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20071029.154258.39630263.davem@davemloft.net>
David Miller wrote:
> From: David Miller <davem@davemloft.net>
> Date: Mon, 29 Oct 2007 15:25:59 -0700 (PDT)
>
>> Can you guys please just state upfront what virtualization
>> issue is made more difficult by features you want to remove?
>
> Sorry, I mentioned "virtualization" because that's been the
> largest majority of the cases being presented lately.
Nope, not virtualization.
>
> I suspect in your case it's some multicast or SCTP thing :-)
>
Neither of these really either, although I should try to see how
SCTP behaves in this configuration.
As Brian said, a customer asked us a question, and we didn't know the
history. No one is trying to remove functionality or features.
We'd just like to know the why, and the answer of "why not" doesn't
fly very well.
Although in the IPv6 case, there might be issues.
-vlad
^ permalink raw reply
* Re: [PATCH 1/2] Convert /proc/net/ipv6_route to seq_file interface
From: Benjamin Thery @ 2007-10-30 13:46 UTC (permalink / raw)
To: Alexey Dobriyan; +Cc: netdev
In-Reply-To: <47273318.9040408@bull.net>
Cosmetic comment:
I forgot to say there are a few indentation "errors" when
I apply your patch. See below.
Benjamin Thery wrote:
> Alexey Dobriyan wrote:
>> One proc_net_create() user less.
>
> Funny, I was working on a similar patch.
>
> See comment below.
>
>
>> Signed-off-by: Alexey Dobriyan <adobriyan@sw.ru>
>> ---
>>
>> net/ipv6/route.c | 70 +++++++++++++++++++------------------------------------
>> 1 file changed, 25 insertions(+), 45 deletions(-)
>>
>> --- a/net/ipv6/route.c
>> +++ b/net/ipv6/route.c
>> @@ -2288,71 +2288,49 @@ struct rt6_proc_arg
>>
>> static int rt6_info_route(struct rt6_info *rt, void *p_arg)
>> {
>> - struct rt6_proc_arg *arg = (struct rt6_proc_arg *) p_arg;
>> + struct seq_file *m = p_arg;
>>
>> - if (arg->skip < arg->offset / RT6_INFO_LEN) {
>> - arg->skip++;
>> - return 0;
>> - }
>> -
>> - if (arg->len >= arg->length)
>> - return 0;
>> -
>> - arg->len += sprintf(arg->buffer + arg->len,
>> - NIP6_SEQFMT " %02x ",
>> - NIP6(rt->rt6i_dst.addr),
>> + seq_printf(m, NIP6_SEQFMT " %02x ", NIP6(rt->rt6i_dst.addr),
>> rt->rt6i_dst.plen);
>>
>> #ifdef CONFIG_IPV6_SUBTREES
>> - arg->len += sprintf(arg->buffer + arg->len,
>> - NIP6_SEQFMT " %02x ",
>> - NIP6(rt->rt6i_src.addr),
>> + seq_printf(m, NIP6_SEQFMT " %02x ", NIP6(rt->rt6i_src.addr),
>> rt->rt6i_src.plen);
Indent is wrong for the above line.
>> #else
>> - arg->len += sprintf(arg->buffer + arg->len,
>> - "00000000000000000000000000000000 00 ");
>> + seq_puts(m, "00000000000000000000000000000000 00 ");
>> #endif
>>
>> if (rt->rt6i_nexthop) {
>> - arg->len += sprintf(arg->buffer + arg->len,
>> - NIP6_SEQFMT,
>> + seq_printf(m, NIP6_SEQFMT,
>> NIP6(*((struct in6_addr *)rt->rt6i_nexthop->primary_key)));
Idem.
>> } else {
>> - arg->len += sprintf(arg->buffer + arg->len,
>> - "00000000000000000000000000000000");
>> + seq_puts(m, "00000000000000000000000000000000");
>> }
>> - arg->len += sprintf(arg->buffer + arg->len,
>> - " %08x %08x %08x %08x %8s\n",
>> + seq_printf(m, " %08x %08x %08x %08x %8s\n",
>> rt->rt6i_metric, atomic_read(&rt->u.dst.__refcnt),
>> rt->u.dst.__use, rt->rt6i_flags,
>> rt->rt6i_dev ? rt->rt6i_dev->name : "");
Indent of the 3 above lines.
>> return 0;
>> }
>>
>> -static int rt6_proc_info(char *buffer, char **start, off_t offset, int length)
>> +static int ipv6_route_show(struct seq_file *m, void *v)
>> {
>> - struct rt6_proc_arg arg = {
>> - .buffer = buffer,
>> - .offset = offset,
>> - .length = length,
>> - };
>> -
>> - fib6_clean_all(rt6_info_route, 0, &arg);
>> -
>> - *start = buffer;
>> - if (offset)
>> - *start += offset % RT6_INFO_LEN;
>> -
>> - arg.len -= offset % RT6_INFO_LEN;
>> -
>> - if (arg.len > length)
>> - arg.len = length;
>> - if (arg.len < 0)
>> - arg.len = 0;
>> + fib6_clean_all(rt6_info_route, 0, m);
>> + return 0;
>> +}
>>
>> - return arg.len;
>> +static int ipv6_route_open(struct inode *inode, struct file *file)
>> +{
>> + return single_open(file, ipv6_route_show, NULL);
>> }
>>
>> +static const struct file_operations ipv6_route_proc_fops = {
>> + .open = ipv6_route_open,
>> + .read = seq_read,
>> + .llseek = seq_lseek,
>> + .release = single_release,
>> +};
>> +
>> static int rt6_stats_seq_show(struct seq_file *seq, void *v)
>> {
>> seq_printf(seq, "%04x %04x %04x %04x %04x %04x %04x\n",
>> @@ -2499,9 +2477,11 @@ void __init ip6_route_init(void)
>>
>> fib6_init();
>> #ifdef CONFIG_PROC_FS
>> - p = proc_net_create(&init_net, "ipv6_route", 0, rt6_proc_info);
>> - if (p)
>
>> + p = create_proc_entry("ipv6_route", 0, init_net.proc_net);
>> + if (p) {
>> p->owner = THIS_MODULE;
>> + p->proc_fops = &ipv6_route_proc_fops;
>> + }
>
> You should use proc_net_fops_create() instead of the above code.
> It does the same thing.
>
> Otherwise the patch looks fine to me.
> Tested on i386.
>
> Benjamin
>
>> proc_net_fops_create(&init_net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops);
>> #endif
>>
>> -
>> To unsubscribe from this list: send the line "unsubscribe netdev" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>
>
--
B e n j a m i n T h e r y - BULL/DT/Open Software R&D
http://www.bull.com
^ permalink raw reply
* Re: [PATCH 1/2] Convert /proc/net/ipv6_route to seq_file interface
From: Benjamin Thery @ 2007-10-30 13:35 UTC (permalink / raw)
To: Alexey Dobriyan; +Cc: netdev
In-Reply-To: <20071030131147.GA6210@localhost.sw.ru>
Alexey Dobriyan wrote:
> One proc_net_create() user less.
Funny, I was working on a similar patch.
See comment below.
> Signed-off-by: Alexey Dobriyan <adobriyan@sw.ru>
> ---
>
> net/ipv6/route.c | 70 +++++++++++++++++++------------------------------------
> 1 file changed, 25 insertions(+), 45 deletions(-)
>
> --- a/net/ipv6/route.c
> +++ b/net/ipv6/route.c
> @@ -2288,71 +2288,49 @@ struct rt6_proc_arg
>
> static int rt6_info_route(struct rt6_info *rt, void *p_arg)
> {
> - struct rt6_proc_arg *arg = (struct rt6_proc_arg *) p_arg;
> + struct seq_file *m = p_arg;
>
> - if (arg->skip < arg->offset / RT6_INFO_LEN) {
> - arg->skip++;
> - return 0;
> - }
> -
> - if (arg->len >= arg->length)
> - return 0;
> -
> - arg->len += sprintf(arg->buffer + arg->len,
> - NIP6_SEQFMT " %02x ",
> - NIP6(rt->rt6i_dst.addr),
> + seq_printf(m, NIP6_SEQFMT " %02x ", NIP6(rt->rt6i_dst.addr),
> rt->rt6i_dst.plen);
>
> #ifdef CONFIG_IPV6_SUBTREES
> - arg->len += sprintf(arg->buffer + arg->len,
> - NIP6_SEQFMT " %02x ",
> - NIP6(rt->rt6i_src.addr),
> + seq_printf(m, NIP6_SEQFMT " %02x ", NIP6(rt->rt6i_src.addr),
> rt->rt6i_src.plen);
> #else
> - arg->len += sprintf(arg->buffer + arg->len,
> - "00000000000000000000000000000000 00 ");
> + seq_puts(m, "00000000000000000000000000000000 00 ");
> #endif
>
> if (rt->rt6i_nexthop) {
> - arg->len += sprintf(arg->buffer + arg->len,
> - NIP6_SEQFMT,
> + seq_printf(m, NIP6_SEQFMT,
> NIP6(*((struct in6_addr *)rt->rt6i_nexthop->primary_key)));
> } else {
> - arg->len += sprintf(arg->buffer + arg->len,
> - "00000000000000000000000000000000");
> + seq_puts(m, "00000000000000000000000000000000");
> }
> - arg->len += sprintf(arg->buffer + arg->len,
> - " %08x %08x %08x %08x %8s\n",
> + seq_printf(m, " %08x %08x %08x %08x %8s\n",
> rt->rt6i_metric, atomic_read(&rt->u.dst.__refcnt),
> rt->u.dst.__use, rt->rt6i_flags,
> rt->rt6i_dev ? rt->rt6i_dev->name : "");
> return 0;
> }
>
> -static int rt6_proc_info(char *buffer, char **start, off_t offset, int length)
> +static int ipv6_route_show(struct seq_file *m, void *v)
> {
> - struct rt6_proc_arg arg = {
> - .buffer = buffer,
> - .offset = offset,
> - .length = length,
> - };
> -
> - fib6_clean_all(rt6_info_route, 0, &arg);
> -
> - *start = buffer;
> - if (offset)
> - *start += offset % RT6_INFO_LEN;
> -
> - arg.len -= offset % RT6_INFO_LEN;
> -
> - if (arg.len > length)
> - arg.len = length;
> - if (arg.len < 0)
> - arg.len = 0;
> + fib6_clean_all(rt6_info_route, 0, m);
> + return 0;
> +}
>
> - return arg.len;
> +static int ipv6_route_open(struct inode *inode, struct file *file)
> +{
> + return single_open(file, ipv6_route_show, NULL);
> }
>
> +static const struct file_operations ipv6_route_proc_fops = {
> + .open = ipv6_route_open,
> + .read = seq_read,
> + .llseek = seq_lseek,
> + .release = single_release,
> +};
> +
> static int rt6_stats_seq_show(struct seq_file *seq, void *v)
> {
> seq_printf(seq, "%04x %04x %04x %04x %04x %04x %04x\n",
> @@ -2499,9 +2477,11 @@ void __init ip6_route_init(void)
>
> fib6_init();
> #ifdef CONFIG_PROC_FS
> - p = proc_net_create(&init_net, "ipv6_route", 0, rt6_proc_info);
> - if (p)
> + p = create_proc_entry("ipv6_route", 0, init_net.proc_net);
> + if (p) {
> p->owner = THIS_MODULE;
> + p->proc_fops = &ipv6_route_proc_fops;
> + }
You should use proc_net_fops_create() instead of the above code.
It does the same thing.
Otherwise the patch looks fine to me.
Tested on i386.
Benjamin
> proc_net_fops_create(&init_net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops);
> #endif
>
> -
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
B e n j a m i n T h e r y - BULL/DT/Open Software R&D
http://www.bull.com
^ permalink raw reply
* [PATCH] DM9601: Support for ADMtek ADM8515 NIC
From: Peter Korsgaard @ 2007-10-30 13:23 UTC (permalink / raw)
To: jeff, netdev
Add device ID for the ADMtek ADM8515 USB NIC to the DM9601 driver.
Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk>
diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c
index a2de32f..2c68573 100644
--- a/drivers/net/usb/dm9601.c
+++ b/drivers/net/usb/dm9601.c
@@ -586,6 +586,10 @@ static const struct usb_device_id products[] = {
USB_DEVICE(0x0a46, 0x0268), /* ShanTou ST268 USB NIC */
.driver_info = (unsigned long)&dm9601_info,
},
+ {
+ USB_DEVICE(0x0a46, 0x8515), /* ADMtek ADM8515 USB NIC */
+ .driver_info = (unsigned long)&dm9601_info,
+ },
{}, // END
};
--
1.5.3.4
--
Bye, Peter Korsgaard
^ permalink raw reply related
* Re: [PATCH] net: Saner thash_entries default with much memory
From: Jean Delvare @ 2007-10-30 13:18 UTC (permalink / raw)
To: David Miller; +Cc: ak, netdev
In-Reply-To: <20071030.005758.184980120.davem@davemloft.net>
Hi David,
Le mardi 30 octobre 2007, David Miller a écrit :
> From: Andi Kleen <ak@suse.de>
> Date: Fri, 26 Oct 2007 17:34:17 +0200
>
> > On Fri, Oct 26, 2007 at 05:21:31PM +0200, Jean Delvare wrote:
> > > I propose 2 millions of entries as the arbitrary high limit. This
> >
> > It's probably still far too large.
>
> I agree. Perhaps a better number is something on the order of
> (512 * 1024) so I think I'll check in a variant of Jean's patch
> with just the limit decreased like that.
That's very fine with me. I originally proposed an admittedly high
limit value to increase the chance to see it accepted. I am not
familiar enough with networking to know what a more reasonable
limit would be, so I'm leaving it to the experts.
> Using just some back of the envelope calculations, on UP 64-bit
> systems each socket uses about 2424 bytes minimum of memory (this is
> the sum of tcp_sock, inode, dentry, socket, and file on sparc64 UP).
> This is an underestimate because it does not even consider things like
> allocator overhead.
>
> Next, machines that service that many sockets typically have them
> mostly with full transmit queues talking to a very slow receiver at
> the other end. So let's estimate that on average each socket consumes
> about 64K of retransmit queue data.
>
> I think this is an extremely conservative estimate beause it doesn't
> even consider overhead coming from struct sk_buff and related state.
>
> So for (512 * 1024) of established sockets we consume roughly 35GB of
> memory, this is '((2424 + (64 * 1024)) * (512 * 1024))'.
>
> So to me (512 * 1024) is a very reasonable limit and (with lockdep
> and spinlock debugging disabled) this makes the EHASH table consume
> 8MB on UP 64-bit and ~12MB on SMP 64-bit systems.
OK, let's go with (512 * 1024) then. Want me to send an updated patch?
Thanks,
--
Jean Delvare
Suse L3
^ permalink raw reply
* [PATCH 2/2] Remove /proc/net/ip_vs_lblcr
From: Alexey Dobriyan @ 2007-10-30 13:12 UTC (permalink / raw)
To: netdev
It's under CONFIG_IP_VS_LBLCR_DEBUG option which never existed.
Signed-off-by: Alexey Dobriyan <adobriyan@sw.ru>
---
I can convert it to seq_file if anyone is secretly using it.
net/ipv4/ipvs/ip_vs_lblcr.c | 76 --------------------------------------------
1 file changed, 76 deletions(-)
--- a/net/ipv4/ipvs/ip_vs_lblcr.c
+++ b/net/ipv4/ipvs/ip_vs_lblcr.c
@@ -48,8 +48,6 @@
/* for sysctl */
#include <linux/fs.h>
#include <linux/sysctl.h>
-/* for proc_net_create/proc_net_remove */
-#include <linux/proc_fs.h>
#include <net/net_namespace.h>
#include <net/ip_vs.h>
@@ -547,71 +545,6 @@ static void ip_vs_lblcr_check_expire(unsigned long data)
mod_timer(&tbl->periodic_timer, jiffies+CHECK_EXPIRE_INTERVAL);
}
-
-#ifdef CONFIG_IP_VS_LBLCR_DEBUG
-static struct ip_vs_lblcr_table *lblcr_table_list;
-
-/*
- * /proc/net/ip_vs_lblcr to display the mappings of
- * destination IP address <==> its serverSet
- */
-static int
-ip_vs_lblcr_getinfo(char *buffer, char **start, off_t offset, int length)
-{
- off_t pos=0, begin;
- int len=0, size;
- struct ip_vs_lblcr_table *tbl;
- unsigned long now = jiffies;
- int i;
- struct ip_vs_lblcr_entry *en;
-
- tbl = lblcr_table_list;
-
- size = sprintf(buffer, "LastTime Dest IP address Server set\n");
- pos += size;
- len += size;
-
- for (i=0; i<IP_VS_LBLCR_TAB_SIZE; i++) {
- read_lock_bh(&tbl->lock);
- list_for_each_entry(en, &tbl->bucket[i], list) {
- char tbuf[16];
- struct ip_vs_dest_list *d;
-
- sprintf(tbuf, "%u.%u.%u.%u", NIPQUAD(en->addr));
- size = sprintf(buffer+len, "%8lu %-16s ",
- now-en->lastuse, tbuf);
-
- read_lock(&en->set.lock);
- for (d=en->set.list; d!=NULL; d=d->next) {
- size += sprintf(buffer+len+size,
- "%u.%u.%u.%u ",
- NIPQUAD(d->dest->addr));
- }
- read_unlock(&en->set.lock);
- size += sprintf(buffer+len+size, "\n");
- len += size;
- pos += size;
- if (pos <= offset)
- len=0;
- if (pos >= offset+length) {
- read_unlock_bh(&tbl->lock);
- goto done;
- }
- }
- read_unlock_bh(&tbl->lock);
- }
-
- done:
- begin = len - (pos - offset);
- *start = buffer + begin;
- len -= begin;
- if(len>length)
- len = length;
- return len;
-}
-#endif
-
-
static int ip_vs_lblcr_init_svc(struct ip_vs_service *svc)
{
int i;
@@ -650,9 +583,6 @@ static int ip_vs_lblcr_init_svc(struct ip_vs_service *svc)
tbl->periodic_timer.expires = jiffies+CHECK_EXPIRE_INTERVAL;
add_timer(&tbl->periodic_timer);
-#ifdef CONFIG_IP_VS_LBLCR_DEBUG
- lblcr_table_list = tbl;
-#endif
return 0;
}
@@ -843,18 +773,12 @@ static int __init ip_vs_lblcr_init(void)
{
INIT_LIST_HEAD(&ip_vs_lblcr_scheduler.n_list);
sysctl_header = register_sysctl_table(lblcr_root_table);
-#ifdef CONFIG_IP_VS_LBLCR_DEBUG
- proc_net_create(&init_net, "ip_vs_lblcr", 0, ip_vs_lblcr_getinfo);
-#endif
return register_ip_vs_scheduler(&ip_vs_lblcr_scheduler);
}
static void __exit ip_vs_lblcr_cleanup(void)
{
-#ifdef CONFIG_IP_VS_LBLCR_DEBUG
- proc_net_remove(&init_net, "ip_vs_lblcr");
-#endif
unregister_sysctl_table(sysctl_header);
unregister_ip_vs_scheduler(&ip_vs_lblcr_scheduler);
}
^ permalink raw reply
* [PATCH 1/2] Convert /proc/net/ipv6_route to seq_file interface
From: Alexey Dobriyan @ 2007-10-30 13:11 UTC (permalink / raw)
To: netdev
One proc_net_create() user less.
Signed-off-by: Alexey Dobriyan <adobriyan@sw.ru>
---
net/ipv6/route.c | 70 +++++++++++++++++++------------------------------------
1 file changed, 25 insertions(+), 45 deletions(-)
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2288,71 +2288,49 @@ struct rt6_proc_arg
static int rt6_info_route(struct rt6_info *rt, void *p_arg)
{
- struct rt6_proc_arg *arg = (struct rt6_proc_arg *) p_arg;
+ struct seq_file *m = p_arg;
- if (arg->skip < arg->offset / RT6_INFO_LEN) {
- arg->skip++;
- return 0;
- }
-
- if (arg->len >= arg->length)
- return 0;
-
- arg->len += sprintf(arg->buffer + arg->len,
- NIP6_SEQFMT " %02x ",
- NIP6(rt->rt6i_dst.addr),
+ seq_printf(m, NIP6_SEQFMT " %02x ", NIP6(rt->rt6i_dst.addr),
rt->rt6i_dst.plen);
#ifdef CONFIG_IPV6_SUBTREES
- arg->len += sprintf(arg->buffer + arg->len,
- NIP6_SEQFMT " %02x ",
- NIP6(rt->rt6i_src.addr),
+ seq_printf(m, NIP6_SEQFMT " %02x ", NIP6(rt->rt6i_src.addr),
rt->rt6i_src.plen);
#else
- arg->len += sprintf(arg->buffer + arg->len,
- "00000000000000000000000000000000 00 ");
+ seq_puts(m, "00000000000000000000000000000000 00 ");
#endif
if (rt->rt6i_nexthop) {
- arg->len += sprintf(arg->buffer + arg->len,
- NIP6_SEQFMT,
+ seq_printf(m, NIP6_SEQFMT,
NIP6(*((struct in6_addr *)rt->rt6i_nexthop->primary_key)));
} else {
- arg->len += sprintf(arg->buffer + arg->len,
- "00000000000000000000000000000000");
+ seq_puts(m, "00000000000000000000000000000000");
}
- arg->len += sprintf(arg->buffer + arg->len,
- " %08x %08x %08x %08x %8s\n",
+ seq_printf(m, " %08x %08x %08x %08x %8s\n",
rt->rt6i_metric, atomic_read(&rt->u.dst.__refcnt),
rt->u.dst.__use, rt->rt6i_flags,
rt->rt6i_dev ? rt->rt6i_dev->name : "");
return 0;
}
-static int rt6_proc_info(char *buffer, char **start, off_t offset, int length)
+static int ipv6_route_show(struct seq_file *m, void *v)
{
- struct rt6_proc_arg arg = {
- .buffer = buffer,
- .offset = offset,
- .length = length,
- };
-
- fib6_clean_all(rt6_info_route, 0, &arg);
-
- *start = buffer;
- if (offset)
- *start += offset % RT6_INFO_LEN;
-
- arg.len -= offset % RT6_INFO_LEN;
-
- if (arg.len > length)
- arg.len = length;
- if (arg.len < 0)
- arg.len = 0;
+ fib6_clean_all(rt6_info_route, 0, m);
+ return 0;
+}
- return arg.len;
+static int ipv6_route_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ipv6_route_show, NULL);
}
+static const struct file_operations ipv6_route_proc_fops = {
+ .open = ipv6_route_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
static int rt6_stats_seq_show(struct seq_file *seq, void *v)
{
seq_printf(seq, "%04x %04x %04x %04x %04x %04x %04x\n",
@@ -2499,9 +2477,11 @@ void __init ip6_route_init(void)
fib6_init();
#ifdef CONFIG_PROC_FS
- p = proc_net_create(&init_net, "ipv6_route", 0, rt6_proc_info);
- if (p)
+ p = create_proc_entry("ipv6_route", 0, init_net.proc_net);
+ if (p) {
p->owner = THIS_MODULE;
+ p->proc_fops = &ipv6_route_proc_fops;
+ }
proc_net_fops_create(&init_net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops);
#endif
^ permalink raw reply
* [IPV6] cleanup : remove proc_net_remove called twice
From: Daniel Lezcano @ 2007-10-30 12:55 UTC (permalink / raw)
To: David Miller, Eric W. Biederman; +Cc: Linux Netdev List, Linux Containers
The file /proc/net/if_inet6 is removed twice.
First time in:
inet6_exit
->addrconf_cleanup
And followed a few lines after by:
inet6_exit
-> if6_proc_exit
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
---
net/ipv6/addrconf.c | 4 ----
1 file changed, 4 deletions(-)
Index: net-2.6/net/ipv6/addrconf.c
===================================================================
--- net-2.6.orig/net/ipv6/addrconf.c
+++ net-2.6/net/ipv6/addrconf.c
@@ -4288,8 +4288,4 @@ void __exit addrconf_cleanup(void)
del_timer(&addr_chk_timer);
rtnl_unlock();
-
-#ifdef CONFIG_PROC_FS
- proc_net_remove(&init_net, "if_inet6");
-#endif
}
^ permalink raw reply
* [PATCH 2.6.24] ixgb: TX hangs under heavy load
From: Andy Gospodarek @ 2007-10-30 12:50 UTC (permalink / raw)
To: auke-jan.h.kok; +Cc: zenyowu, netdev
Auke,
It has become clear that this patch resolves some tx-lockups on the ixgb
driver. IBM did some checking and realized this hunk is in your
sourceforge driver, but not anywhere else. Mind if we add it?
Thanks,
-andy
Signed-off-by: Andy Gospodarek <andy@greyhouse.net>
---
ixgb_main.c | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index d444de5..3ec7a41 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -1324,7 +1324,7 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
/* Workaround for premature desc write-backs
* in TSO mode. Append 4-byte sentinel desc */
- if (unlikely(mss && !nr_frags && size == len
+ if (unlikely(mss && (f == (nr_frags-1)) && size == len
&& size > 8))
size -= 4;
^ permalink raw reply related
* [PATCH][NETNS] fix net released by rcu callback
From: Daniel Lezcano @ 2007-10-30 10:33 UTC (permalink / raw)
To: David Miller, Eric W. Biederman; +Cc: Linux Netdev List, Linux Containers
When a network namespace reference is held by a network subsystem,
and when this reference is decremented in a rcu update callback, we
must ensure that there is no more outstanding rcu update before
trying to free the network namespace.
In the normal case, the rcu_barrier is called when the network namespace
is exiting in the cleanup_net function.
But when a network namespace creation fails, and the subsystems are
undone (like the cleanup), the rcu_barrier is missing.
This patch adds the missing rcu_barrier.
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
---
net/core/net_namespace.c | 2 ++
1 file changed, 2 insertions(+)
Index: net-2.6/net/core/net_namespace.c
===================================================================
--- net-2.6.orig/net/core/net_namespace.c
+++ net-2.6/net/core/net_namespace.c
@@ -112,6 +112,8 @@ out_undo:
if (ops->exit)
ops->exit(net);
}
+
+ rcu_barrier();
goto out;
}
^ permalink raw reply
* [PATCH] core: fix free_netdev when register fails during notification call chain
From: Daniel Lezcano @ 2007-10-30 10:20 UTC (permalink / raw)
To: David Miller; +Cc: Linux Netdev List
Point 1:
The unregistering of a network device schedule a netdev_run_todo.
This function calls dev->destructor when it is set and the
destructor calls free_netdev.
Point 2:
In the case of an initialization of a network device the usual code
is:
* alloc_netdev
* register_netdev
-> if this one fails, call free_netdev and exit with error.
Point 3:
In the register_netdevice function at the later state, when the device
is at the registered state, a call to the netdevice_notifiers is made.
If one of the notification falls into an error, a rollback to the
registered state is done using unregister_netdevice.
Conclusion:
When a network device fails to register during initialization because
one network subsystem returned an error during a notification call
chain, the network device is freed twice because of fact 1 and fact 2.
The second free_netdev will be done with an invalid pointer.
Proposed solution:
The following patch move all the code of unregister_netdevice *except*
the call to net_set_todo, to a new function "rollback_registered".
The following functions are changed in this way:
* register_netdevice: calls rollback_registered when a notification fails
* unregister_netdevice: calls rollback_register + net_set_todo, the call
order to net_set_todo is changed because it is the
latest now. Since it justs add an element to a
list
that should not break anything.
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
---
net/core/dev.c | 112
++++++++++++++++++++++++++++++---------------------------
1 file changed, 59 insertions(+), 53 deletions(-)
Index: net-2.6/net/core/dev.c
===================================================================
--- net-2.6.orig/net/core/dev.c
+++ net-2.6/net/core/dev.c
@@ -3496,6 +3496,60 @@ static void net_set_todo(struct net_devi
spin_unlock(&net_todo_list_lock);
}
+static void rollback_registered(struct net_device *dev)
+{
+ BUG_ON(dev_boot_phase);
+ ASSERT_RTNL();
+
+ /* Some devices call without registering for initialization unwind. */
+ if (dev->reg_state == NETREG_UNINITIALIZED) {
+ printk(KERN_DEBUG "unregister_netdevice: device %s/%p never "
+ "was registered\n", dev->name, dev);
+
+ WARN_ON(1);
+ return;
+ }
+
+ BUG_ON(dev->reg_state != NETREG_REGISTERED);
+
+ /* If device is running, close it first. */
+ dev_close(dev);
+
+ /* And unlink it from device chain. */
+ unlist_netdevice(dev);
+
+ dev->reg_state = NETREG_UNREGISTERING;
+
+ synchronize_net();
+
+ /* Shutdown queueing discipline. */
+ dev_shutdown(dev);
+
+
+ /* Notify protocols, that we are about to destroy
+ this device. They should clean all the things.
+ */
+ call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
+
+ /*
+ * Flush the unicast and multicast chains
+ */
+ dev_addr_discard(dev);
+
+ if (dev->uninit)
+ dev->uninit(dev);
+
+ /* Notifier chain MUST detach us from master device. */
+ BUG_TRAP(!dev->master);
+
+ /* Remove entries from kobject tree */
+ netdev_unregister_kobject(dev);
+
+ synchronize_net();
+
+ dev_put(dev);
+}
+
/**
* register_netdevice - register a network device
* @dev: device to register
@@ -3633,8 +3687,10 @@ int register_netdevice(struct net_device
/* Notify protocols, that a new device appeared. */
ret = call_netdevice_notifiers(NETDEV_REGISTER, dev);
ret = notifier_to_errno(ret);
- if (ret)
- unregister_netdevice(dev);
+ if (ret) {
+ rollback_registered(dev);
+ dev->reg_state = NETREG_UNREGISTERED;
+ }
out:
return ret;
@@ -3911,59 +3967,9 @@ void synchronize_net(void)
void unregister_netdevice(struct net_device *dev)
{
- BUG_ON(dev_boot_phase);
- ASSERT_RTNL();
-
- /* Some devices call without registering for initialization unwind. */
- if (dev->reg_state == NETREG_UNINITIALIZED) {
- printk(KERN_DEBUG "unregister_netdevice: device %s/%p never "
- "was registered\n", dev->name, dev);
-
- WARN_ON(1);
- return;
- }
-
- BUG_ON(dev->reg_state != NETREG_REGISTERED);
-
- /* If device is running, close it first. */
- dev_close(dev);
-
- /* And unlink it from device chain. */
- unlist_netdevice(dev);
-
- dev->reg_state = NETREG_UNREGISTERING;
-
- synchronize_net();
-
- /* Shutdown queueing discipline. */
- dev_shutdown(dev);
-
-
- /* Notify protocols, that we are about to destroy
- this device. They should clean all the things.
- */
- call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
-
- /*
- * Flush the unicast and multicast chains
- */
- dev_addr_discard(dev);
-
- if (dev->uninit)
- dev->uninit(dev);
-
- /* Notifier chain MUST detach us from master device. */
- BUG_TRAP(!dev->master);
-
- /* Remove entries from kobject tree */
- netdev_unregister_kobject(dev);
-
+ rollback_registered(dev);
/* Finish processing unregister after unlock */
net_set_todo(dev);
-
- synchronize_net();
-
- dev_put(dev);
}
/**
^ permalink raw reply
* Re: [PATCH] pegasos_eth.c: Fix compile error over MV643XX_ defines
From: Dale Farnsworth @ 2007-10-30 10:22 UTC (permalink / raw)
To: Sven Luther
Cc: Luis R. Rodriguez, netdev, Tzachi Perelstein, Lennert Buytenhek,
Jeff Garzik, linuxppc-dev
In-Reply-To: <20071030093606.GA20920@powerlinux.fr>
On Tue, Oct 30, 2007 at 10:36:06AM +0100, Sven Luther wrote:
> On Tue, Oct 30, 2007 at 03:44:59AM -0400, Luis R. Rodriguez wrote:
> > On 10/29/07, Dale Farnsworth <dale@farnsworth.org> wrote:
> > > On Mon, Oct 29, 2007 at 05:27:29PM -0400, Luis R. Rodriguez wrote:
> > > > This commit made an incorrect assumption:
> > > > --
> > > > Author: Lennert Buytenhek <buytenh@wantstofly.org>
> > > > Date: Fri Oct 19 04:10:10 2007 +0200
> > > >
> > > > mv643xx_eth: Move ethernet register definitions into private header
> > > >
> > > > Move the mv643xx's ethernet-related register definitions from
> > > > include/linux/mv643xx.h into drivers/net/mv643xx_eth.h, since
> > > > they aren't of any use outside the ethernet driver.
> > > >
> > > > Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
> > > > Acked-by: Tzachi Perelstein <tzachi@marvell.com>
> > > > Signed-off-by: Dale Farnsworth <dale@farnsworth.org>
> > > > --
> > > >
> > > > arch/powerpc/platforms/chrp/pegasos_eth.c made use of a 3 defines there.
> > > >
> > > > mcgrof@pogo:~/devel/wireless-2.6$ git-describe
> > > >
> > > > v2.6.24-rc1-138-g0119130
> > > >
> > > > This patch fixes this by internalizing 3 defines onto pegasos which are
> > > > simply no longer available elsewhere. Without this your compile will fail
> > >
> > > That compile failure was fixed in commit
> > > 30e69bf4cce16d4c2dcfd629a60fcd8e1aba9fee by Al Viro.
> > >
> > > However, as I examine that commit, I see that it defines offsets from
> > > the eth block in the chip, rather than the full chip registeri block
> > > as the Pegasos 2 code expects. So, I think it fixes the compile
> > > failure, but leaves the Pegasos 2 broken.
> > >
> > > Luis, do you have Pegasos 2 hardware? Can you (or anyone) verify that
> > > the following patch is needed for the Pegasos 2?
> >
> > Nope, sorry.
>
> I am busy right now, but have various pegasos machines available for
> testing. What exactly should i test ?
Thanks Sven.
Test whether an Ethernet port works at all. I think it's currently
broken, but should work with the patch I supplied.
-Dale
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox