* Re: [PATCH for 2.6.31] cxgb3: Fix crash caused by stashing wrong netdev_queue
From: David Miller @ 2009-07-10 0:16 UTC (permalink / raw)
To: divy; +Cc: rdreier, netdev
In-Reply-To: <4A565DE9.3040504@chelsio.com>
From: Divy Le Ray <divy@chelsio.com>
Date: Thu, 09 Jul 2009 14:15:21 -0700
> Roland Dreier wrote:
>> Commit c3a8c5b6 ("cxgb3: move away from LLTX") exposed a bug in how
>> cxgb3 looks up the netdev_queue it stashes away in a qset during
>> initialization. For multiport devices, the TX queue index it uses is
>> offset by the first_qset index of each port. This leads to a crash
>> once LLTX is removed, since hard_start_xmit is called with one TX
>> queue lock held, while the TX reclaim timer task grabs a different
>> (wrong) TX queue lock when it frees skbs.
>>
>> Fix this by removing the first_qset offset used to look up the TX
>> queue passed into t3_sge_alloc_qset() from setup_sge_qsets().
>>
>
> Thanks Roland!
> You were very fast to fix it, you beat us.
>
> Acked-by: Divy Le Ray <divy@chelsio.com>
>
>> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Applied.
^ permalink raw reply
* Re: sk_lock: inconsistent {RECLAIM_FS-ON-W} -> {IN-RECLAIM_FS-W} usage
From: David Miller @ 2009-07-10 0:13 UTC (permalink / raw)
To: fengguang.wu-ral2JQCrhuEAvxtiuMwx3w
Cc: herbert-lOAM2aK0SrRLBo1qDEOMRrpzq4S04n8Q,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-nfs-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20090709131746.GA27965@localhost>
From: Wu Fengguang <fengguang.wu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Date: Thu, 9 Jul 2009 21:17:46 +0800
> @@ -2100,7 +2100,8 @@ void tcp_send_fin(struct sock *sk)
> } else {
> /* Socket is locked, keep trying until memory is available. */
> for (;;) {
> - skb = alloc_skb_fclone(MAX_TCP_HEADER, GFP_KERNEL);
> + skb = alloc_skb_fclone(MAX_TCP_HEADER,
> + sk->sk_allocation);
> if (skb)
> break;
> yield();
I think this specific case needs more thinking.
If the allocation fails, and it's GFP_ATOMIC, we are going to yield()
(which sleeps) and loop endlessly waiting for the allocation to
succeed.
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: patch acceptance question
From: David Miller @ 2009-07-10 0:10 UTC (permalink / raw)
To: pcnet32; +Cc: netdev
In-Reply-To: <1247152896.29603.15.camel@localhost.localdomain>
From: Don Fry <pcnet32@verizon.net>
Date: Thu, 09 Jul 2009 08:21:36 -0700
> I was surprised today to see a change to pcnet32.c in 2.6.31-rc2-git4
> which maybe I missed yesterday on netdev. Most of the changes are okay,
> but one in particular will result in some ugly printing.
>
> What is the path that (probably janitorial) changes take that get
> included in mainline? Had I seen it before it went in I would have
> commented on it then.
In the amount of typing you did for sending this email, you
could have submitted a fix instead.
I think the change in question went straight into Linus's tree.
^ permalink raw reply
* Re: [PATCHv7 2/2] memory barrier: adding smp_mb__after_lock
From: David Miller @ 2009-07-10 0:08 UTC (permalink / raw)
To: eric.dumazet
Cc: jolsa, netdev, mathieu.desnoyers, mingo, a.p.zijlstra,
linux-kernel, fbl, nhorman, htejun, jarkao2, oleg, davidel
In-Reply-To: <4A557153.8000108@gmail.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 09 Jul 2009 06:25:55 +0200
> Jiri Olsa a écrit :
>> Adding smp_mb__after_lock define to be used as a smp_mb call after
>> a lock.
>>
>> Making it nop for x86, since {read|write|spin}_lock() on x86 are
>> full memory barriers.
>>
>> wbr,
>> jirka
>>
>>
>> Signed-off-by: Jiri Olsa <jolsa@redhat.com>
>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Also applied, thanks everyone!
^ permalink raw reply
* Re: [PATCHv7 1/2] net: adding memory barrier to the poll and receive callbacks
From: David Miller @ 2009-07-10 0:08 UTC (permalink / raw)
To: eric.dumazet
Cc: jolsa, netdev, mathieu.desnoyers, mingo, a.p.zijlstra,
linux-kernel, fbl, nhorman, htejun, jarkao2, oleg, davidel
In-Reply-To: <4A5570E7.4010901@gmail.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 09 Jul 2009 06:24:07 +0200
> Jiri Olsa a écrit :
>> Signed-off-by: Jiri Olsa <jolsa@redhat.com>
>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Applied.
^ permalink raw reply
* Re: weird problem
From: Paweł Staszewski @ 2009-07-09 23:59 UTC (permalink / raw)
To: Jarek Poplawski
Cc: Eric Dumazet, Eric Dumazet, Linux Network Development list
In-Reply-To: <4A5679CC.800@itcare.pl>
[-- Attachment #1: Type: text/plain, Size: 5499 bytes --]
Today i make other tests with change of
/proc/sys/net/ipv4/rt_cache_rebuild_count and kernel 2.6.30.1
And when rt_cache_rebuild_count is set to "-1" i have always load on
x86_64 machine approx 40-50% of each cpu where network card is binded by
irq_aff
when rt_cache_rebuild_count is set to more than "-1" i have 15 to 20 sec
of 1 to 3% cpu and after 40-50% cpu
I attach some oprofile output for
rt_cache_rebuild_count = 4 - oprofile_rt_cache_rebuild_count_4.txt
and
rt_cache_rebuild_count = -1 - oprofile_rt_cache_rebuild_count_-1.txt
Regards
Pawel Staszewski
Paweł Staszewski pisze:
> Jarek Poplawski pisze:
>> Pawel Staszewski wrote, On 06/30/2009 10:36 AM:
>> ...
>>
>>>>>>> rt_worker_func() taking 13% of cpu0 is an alarm for me :)
>>>>>>> And 21% of cpu0 and 34% of cpu6 taken by oprofiled seems odd too...
>>>>>>>
>>
>> Pawel, here is a patch which changes this function (or what it calls)
>> back to 2.6.28 version; I'm not sure it's OK, so try it very
>> cautiously...
>>
>> Cheers,
>> Jarek P.
>> --- (for debugging only; apply to 2.6.29.5 or .6)
>>
>>
> I added this patch 30min ago - all is working but problem still exist.
>
> There is only one change - without this patch cpu load was rising from
> 40 to 50%
> With this patch there is 15 to 25% cpu load.
>
>
>> diff -Nurp a/net/ipv4/route.c b/net/ipv4/route.c
>> --- a/net/ipv4/route.c 2009-07-08 23:42:15.000000000 +0200
>> +++ b/net/ipv4/route.c 2009-07-08 22:47:52.000000000 +0200
>> @@ -769,24 +769,11 @@ static void rt_do_flush(int process_cont
>> }
>> }
>>
>> -/*
>> - * While freeing expired entries, we compute average chain length
>> - * and standard deviation, using fixed-point arithmetic.
>> - * This to have an estimation of rt_chain_length_max
>> - * rt_chain_length_max = max(elasticity, AVG + 4*SD)
>> - * We use 3 bits for frational part, and 29 (or 61) for magnitude.
>> - */
>> -
>> -#define FRACT_BITS 3
>> -#define ONE (1UL << FRACT_BITS)
>> -
>> static void rt_check_expire(void)
>> {
>> static unsigned int rover;
>> unsigned int i = rover, goal;
>> - struct rtable *rth, *aux, **rthp;
>> - unsigned long samples = 0;
>> - unsigned long sum = 0, sum2 = 0;
>> + struct rtable *rth, **rthp;
>> u64 mult;
>>
>> mult = ((u64)ip_rt_gc_interval) << rt_hash_log;
>> @@ -797,7 +784,6 @@ static void rt_check_expire(void)
>> goal = rt_hash_mask + 1;
>> for (; goal > 0; goal--) {
>> unsigned long tmo = ip_rt_gc_timeout;
>> - unsigned long length;
>>
>> i = (i + 1) & rt_hash_mask;
>> rthp = &rt_hash_table[i].chain;
>> @@ -805,14 +791,10 @@ static void rt_check_expire(void)
>> if (need_resched())
>> cond_resched();
>>
>> - samples++;
>> -
>> if (*rthp == NULL)
>> continue;
>> - length = 0;
>> spin_lock_bh(rt_hash_lock_addr(i));
>> while ((rth = *rthp) != NULL) {
>> - prefetch(rth->u.dst.rt_next);
>> if (rt_is_expired(rth)) {
>> *rthp = rth->u.dst.rt_next;
>> rt_free(rth);
>> @@ -821,46 +803,23 @@ static void rt_check_expire(void)
>> if (rth->u.dst.expires) {
>> /* Entry is expired even if it is in use */
>> if (time_before_eq(jiffies, rth->u.dst.expires)) {
>> -nofree:
>> tmo >>= 1;
>> rthp = &rth->u.dst.rt_next;
>> - /*
>> - * We only count entries on
>> - * a chain with equal hash inputs once
>> - * so that entries for different QOS
>> - * levels, and other non-hash input
>> - * attributes don't unfairly skew
>> - * the length computation
>> - */
>> - for (aux = rt_hash_table[i].chain;;) {
>> - if (aux == rth) {
>> - length += ONE;
>> - break;
>> - }
>> - if (compare_hash_inputs(&aux->fl, &rth->fl))
>> - break;
>> - aux = aux->u.dst.rt_next;
>> - }
>> continue;
>> }
>> - } else if (!rt_may_expire(rth, tmo, ip_rt_gc_timeout))
>> - goto nofree;
>> + } else if (!rt_may_expire(rth, tmo, ip_rt_gc_timeout)) {
>> + tmo >>= 1;
>> + rthp = &rth->u.dst.rt_next;
>> + continue;
>> + }
>>
>> /* Cleanup aged off entries. */
>> *rthp = rth->u.dst.rt_next;
>> rt_free(rth);
>> }
>> spin_unlock_bh(rt_hash_lock_addr(i));
>> - sum += length;
>> - sum2 += length*length;
>> - }
>> - if (samples) {
>> - unsigned long avg = sum / samples;
>> - unsigned long sd = int_sqrt(sum2 / samples - avg*avg);
>> - rt_chain_length_max = max_t(unsigned long,
>> - ip_rt_gc_elasticity,
>> - (avg + 4*sd) >> FRACT_BITS);
>> }
>> + rt_chain_length_max = ip_rt_gc_elasticity;
>> rover = i;
>> }
>>
>>
>>
>>
>
> --
> 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
>
>
[-- Attachment #2: oprofile_rt_cache_rebuild_count_4.txt --]
[-- Type: text/plain, Size: 5411 bytes --]
CPU: Core 2, speed 2999.65 MHz (estimated)
Counted CPU_CLK_UNHALTED events (Clock cycles when not halted) with a unit mask of 0x00 (Unhalted core cycles) count 100000
Samples on CPU 0
Samples on CPU 1
Samples on CPU 2
Samples on CPU 3
Samples on CPU 4
Samples on CPU 5
Samples on CPU 6
Samples on CPU 7
samples % samples % samples % samples % samples % samples % samples % samples % image name
app name symbol name
2051 17.8488 0 0 0 0 0 0 0 0 0 0 0 0 0 0 oprofiled
oprofiled (no symbols)
1845 16.0560 16362 4.7340 22049 4.2067 1949 16.5197 100 9.6618 43 10.2625 95 10.5205 49 2.3512 vmlinux
vmlinux mwait_idle
1126 9.7990 0 0 0 0 0 0 0 0 0 0 0 0 0 0 vmlinux
vmlinux rt_worker_func
751 6.5355 51 0.0148 53 0.0101 5 0.0424 3 0.2899 0 0 4 0.4430 16 0.7678 vmlinux
vmlinux free_block
621 5.4042 0 0 4 7.6e-04 3766 31.9207 1 0.0966 0 0 0 0 686 32.9175 opreport
opreport (no symbols)
568 4.9430 25 0.0072 38 0.0073 0 0 0 0 0 0 0 0 0 0 vmlinux
vmlinux dst_destroy
303 2.6368 2 5.8e-04 6 0.0011 106 0.8985 0 0 0 0 5 0.5537 26 1.2476 vmlinux
vmlinux copy_user_generic_string
296 2.5759 17175 4.9692 23050 4.3977 196 1.6613 59 5.7005 28 6.6826 71 7.8627 63 3.0230 vmlinux
vmlinux _raw_spin_lock
267 2.3236 21 0.0061 3044 0.5808 1328 11.2561 3 0.2899 1 0.2387 26 2.8793 265 12.7159 libc-2.8.so
libc-2.8.so (no symbols)
261 2.2713 0 0 1 1.9e-04 36 0.3051 0 0 0 0 1 0.1107 6 0.2879 vmlinux
vmlinux search_by_key
247 2.1495 9 0.0026 21 0.0040 3 0.0254 1 0.0966 0 0 0 0 0 0 vmlinux
vmlinux __call_rcu
219 1.9058 0 0 0 0 1177 9.9763 0 0 0 0 0 0 247 11.8522 libstdc++.so.6
.0.10 libstdc++.so.6.0.10 (no symbols)
150 1.3054 1606 0.4647 2104 0.4014 5 0.0424 2 0.1932 3 0.7160 2 0.2215 1 0.0480 vmlinux
vmlinux get_next_timer_interrupt
138 1.2009 15 0.0043 23 0.0044 2 0.0170 2 0.1932 0 0 3 0.3322 1 0.0480 vmlinux
vmlinux __rcu_process_callbacks
105 0.9138 321 0.0929 368 0.0702 44 0.3729 271 26.1836 54 12.8878 63 6.9767 57 2.7351 vmlinux
vmlinux tg_shares_up
100 0.8702 27 0.0078 16 0.0031 0 0 0 0 0 0 0 0 0 0 vmlinux
vmlinux memmove
88 0.7658 1 2.9e-04 7 0.0013 488 4.1363 0 0 0 0 16 1.7719 121 5.8061 vmlinux
vmlinux clear_page_c
86 0.7484 0 0 0 0 454 3.8481 0 0 0 0 0 0 96 4.6065 libbfd-2.18.so
libbfd-2.18.so (no symbols)
65 0.5657 0 0 2 3.8e-04 2 0.0170 0 0 0 0 0 0 0 0 vmlinux
vmlinux __find_get_block
62 0.5396 1536 0.4444 3313 0.6321 15 0.1271 4 0.3865 0 0 4 0.4430 5 0.2399 vmlinux
vmlinux _raw_spin_unlock
57 0.4960 0 0 0 0 0 0 0 0 0 0 0 0 0 0 vmlinux
vmlinux create_virtual_node
52 0.4525 6 0.0017 0 0 930 7.8827 50 4.8309 163 38.9021 95 10.5205 13 0.6238 vmlinux
vmlinux mutex_spin_on_owner
50 0.4351 2 5.8e-04 2 3.8e-04 0 0 0 0 0 0 0 0 0 0 vmlinux
vmlinux dst_rcu_free
49 0.4264 477 0.1380 871 0.1662 2 0.0170 1 0.0966 0 0 0 0 1 0.0480 vmlinux
[-- Attachment #3: oprofile_rt_cache_rebuild_count_-1.txt --]
[-- Type: text/plain, Size: 5414 bytes --]
CPU: Core 2, speed 2999.65 MHz (estimated)
Counted CPU_CLK_UNHALTED events (Clock cycles when not halted) with a unit mask of 0x00 (Unhalted core cycles) count 100000
Samples on CPU 0
Samples on CPU 1
Samples on CPU 2
Samples on CPU 3
Samples on CPU 4
Samples on CPU 5
Samples on CPU 6
Samples on CPU 7
samples % samples % samples % samples % samples % samples % samples % samples % image name
app name symbol name
5233 15.7190 760 0.0795 259 0.0190 10 0.1857 0 0 1 0.1247 340 9.6454 20 1.4006 libc-2.8.so
libc-2.8.so (no symbols)
5116 15.3675 0 0 0 0 0 0 0 0 0 0 0 0 0 0 bgpd
bgpd bgp_best_selection
4499 13.5142 37423 3.9162 47399 3.4832 4615 85.7010 918 9.9804 172 21.4464 540 15.3191 191 13.3754 vmlinux
vmlinux mwait_idle
3635 10.9189 0 0 2102 0.1545 0 0 0 0 0 0 0 0 0 0 oprofiled
oprofiled (no symbols)
2855 8.5759 765 0.0801 0 0 0 0 0 0 0 0 0 0 0 0 bgpd
bgpd bgp_route_next
1626 4.8842 372 0.0389 0 0 0 0 0 0 0 0 0 0 0 0 bgpd
bgpd bgp_scan_timer
1611 4.8391 0 0 0 0 0 0 0 0 0 0 0 0 0 0 bgpd
bgpd bgp_process_main
1133 3.4033 1 1.0e-04 0 0 0 0 0 0 0 0 0 0 0 0 bgpd
bgpd bgp_process_announce_selected
950 2.8536 218 0.0228 0 0 0 0 0 0 0 0 0 0 0 0 bgpd
bgpd bgp_process
486 1.4599 11 0.0012 240 0.0176 1 0.0186 0 0 0 0 31 0.8794 1 0.0700 vmlinux
vmlinux copy_user_generic_string
442 1.3277 111 0.0116 0 0 0 0 0 0 0 0 0 0 0 0 bgpd
bgpd bgp_nexthop_lookup
376 1.1294 1 1.0e-04 0 0 0 0 0 0 0 0 0 0 0 0 libzebra.so.0.
0.0 libzebra.so.0.0.0 work_queue_run
323 0.9702 82 0.0086 2 1.5e-04 0 0 0 0 0 0 0 0 0 0 libzebra.so.0.
0.0 libzebra.so.0.0.0 prefix_match
237 0.7119 64 0.0067 1 7.3e-05 0 0 0 0 0 0 0 0 0 0 libzebra.so.0.
0.0 libzebra.so.0.0.0 zcalloc
216 0.6488 0 0 0 0 0 0 0 0 0 0 0 0 0 0 vmlinux
vmlinux rt_worker_func
203 0.6098 3070 0.3213 4038 0.2967 7 0.1300 32 0.3479 13 1.6209 3 0.0851 6 0.4202 vmlinux
vmlinux get_next_timer_interrupt
192 0.5767 30 0.0031 0 0 0 0 0 0 0 0 0 0 0 0 libzebra.so.0.
0.0 libzebra.so.0.0.0 .plt
189 0.5677 0 0 0 0 0 0 0 0 0 0 0 0 0 0 bgpd
bgpd bgp_adj_out_unset
187 0.5617 40562 4.2447 54422 3.9993 65 1.2071 409 4.4466 73 9.1022 126 3.5745 116 8.1232 vmlinux
vmlinux _raw_spin_lock
144 0.4325 60 0.0063 3 2.2e-04 0 0 0 0 0 0 0 0 0 0 bgpd
bgpd bgp_node_get
127 0.3815 40 0.0042 0 0 0 0 0 0 0 0 0 0 0 0 libzebra.so.0.
0.0 libzebra.so.0.0.0 listnode_add
124 0.3725 1183 0.1238 1623 0.1193 72 1.3370 2894 31.4634 90 11.2219 108 3.0638 191 13.3754 vmlinux
vmlinux tg_shares_up
119 0.3575 0 0 13 9.6e-04 0 0 0 0 0 0 0 0 0 0 vmlinux
vmlinux mutex_spin_on_owner
114 0.3424 14 0.0015 0 0 0 0 0 0 0 0 0 0 0 0 bgpd
^ permalink raw reply
* Re: [PATCH for 2.6.31] cxgb3: Fix crash caused by stashing wrong netdev_queue
From: Roland Dreier @ 2009-07-09 23:16 UTC (permalink / raw)
To: Divy Le Ray; +Cc: David S. Miller, netdev
In-Reply-To: <4A565DE9.3040504@chelsio.com>
> You were very fast to fix it, you beat us.
motivated -- I wanted to be able to use the system where I saw the crash :)
^ permalink raw reply
* Re: weird problem
From: Paweł Staszewski @ 2009-07-09 23:14 UTC (permalink / raw)
To: Jarek Poplawski
Cc: Eric Dumazet, Eric Dumazet, Linux Network Development list
In-Reply-To: <20090708223459.GB3666@ami.dom.local>
Jarek Poplawski pisze:
> Pawel Staszewski wrote, On 06/30/2009 10:36 AM:
> ...
>
>>>>>> rt_worker_func() taking 13% of cpu0 is an alarm for me :)
>>>>>> And 21% of cpu0 and 34% of cpu6 taken by oprofiled seems odd too...
>>>>>>
>
> Pawel, here is a patch which changes this function (or what it calls)
> back to 2.6.28 version; I'm not sure it's OK, so try it very
> cautiously...
>
> Cheers,
> Jarek P.
> --- (for debugging only; apply to 2.6.29.5 or .6)
>
>
I added this patch 30min ago - all is working but problem still exist.
There is only one change - without this patch cpu load was rising from
40 to 50%
With this patch there is 15 to 25% cpu load.
> diff -Nurp a/net/ipv4/route.c b/net/ipv4/route.c
> --- a/net/ipv4/route.c 2009-07-08 23:42:15.000000000 +0200
> +++ b/net/ipv4/route.c 2009-07-08 22:47:52.000000000 +0200
> @@ -769,24 +769,11 @@ static void rt_do_flush(int process_cont
> }
> }
>
> -/*
> - * While freeing expired entries, we compute average chain length
> - * and standard deviation, using fixed-point arithmetic.
> - * This to have an estimation of rt_chain_length_max
> - * rt_chain_length_max = max(elasticity, AVG + 4*SD)
> - * We use 3 bits for frational part, and 29 (or 61) for magnitude.
> - */
> -
> -#define FRACT_BITS 3
> -#define ONE (1UL << FRACT_BITS)
> -
> static void rt_check_expire(void)
> {
> static unsigned int rover;
> unsigned int i = rover, goal;
> - struct rtable *rth, *aux, **rthp;
> - unsigned long samples = 0;
> - unsigned long sum = 0, sum2 = 0;
> + struct rtable *rth, **rthp;
> u64 mult;
>
> mult = ((u64)ip_rt_gc_interval) << rt_hash_log;
> @@ -797,7 +784,6 @@ static void rt_check_expire(void)
> goal = rt_hash_mask + 1;
> for (; goal > 0; goal--) {
> unsigned long tmo = ip_rt_gc_timeout;
> - unsigned long length;
>
> i = (i + 1) & rt_hash_mask;
> rthp = &rt_hash_table[i].chain;
> @@ -805,14 +791,10 @@ static void rt_check_expire(void)
> if (need_resched())
> cond_resched();
>
> - samples++;
> -
> if (*rthp == NULL)
> continue;
> - length = 0;
> spin_lock_bh(rt_hash_lock_addr(i));
> while ((rth = *rthp) != NULL) {
> - prefetch(rth->u.dst.rt_next);
> if (rt_is_expired(rth)) {
> *rthp = rth->u.dst.rt_next;
> rt_free(rth);
> @@ -821,46 +803,23 @@ static void rt_check_expire(void)
> if (rth->u.dst.expires) {
> /* Entry is expired even if it is in use */
> if (time_before_eq(jiffies, rth->u.dst.expires)) {
> -nofree:
> tmo >>= 1;
> rthp = &rth->u.dst.rt_next;
> - /*
> - * We only count entries on
> - * a chain with equal hash inputs once
> - * so that entries for different QOS
> - * levels, and other non-hash input
> - * attributes don't unfairly skew
> - * the length computation
> - */
> - for (aux = rt_hash_table[i].chain;;) {
> - if (aux == rth) {
> - length += ONE;
> - break;
> - }
> - if (compare_hash_inputs(&aux->fl, &rth->fl))
> - break;
> - aux = aux->u.dst.rt_next;
> - }
> continue;
> }
> - } else if (!rt_may_expire(rth, tmo, ip_rt_gc_timeout))
> - goto nofree;
> + } else if (!rt_may_expire(rth, tmo, ip_rt_gc_timeout)) {
> + tmo >>= 1;
> + rthp = &rth->u.dst.rt_next;
> + continue;
> + }
>
> /* Cleanup aged off entries. */
> *rthp = rth->u.dst.rt_next;
> rt_free(rth);
> }
> spin_unlock_bh(rt_hash_lock_addr(i));
> - sum += length;
> - sum2 += length*length;
> - }
> - if (samples) {
> - unsigned long avg = sum / samples;
> - unsigned long sd = int_sqrt(sum2 / samples - avg*avg);
> - rt_chain_length_max = max_t(unsigned long,
> - ip_rt_gc_elasticity,
> - (avg + 4*sd) >> FRACT_BITS);
> }
> + rt_chain_length_max = ip_rt_gc_elasticity;
> rover = i;
> }
>
>
>
>
^ permalink raw reply
* [patch 3/3] net: use HRTIMER_RESTART in sched_cbq
From: Thomas Gleixner @ 2009-07-09 21:59 UTC (permalink / raw)
To: netdev; +Cc: LKML, David Miller, Patrick McHardy, Peter Zijlstra
In-Reply-To: <20090709215455.703939259@linutronix.de>
[-- Attachment #1: net-sched-cbq-use-hrtimer-restart.patch --]
[-- Type: text/plain, Size: 1320 bytes --]
Restarting a hrtimer from the callback function via hrtimer_start is
inefficient. The canonical way is to modify the expiry value of the
timer and return HRTIMER_RESTART to the hrtimer core code which takes
care of the restart.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
net/sched/sch_cbq.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
Index: linux-2.6/net/sched/sch_cbq.c
===================================================================
--- linux-2.6.orig/net/sched/sch_cbq.c
+++ linux-2.6/net/sched/sch_cbq.c
@@ -605,6 +605,7 @@ static enum hrtimer_restart cbq_undelay(
struct cbq_sched_data *q = container_of(timer, struct cbq_sched_data,
delay_timer);
struct Qdisc *sch = q->watchdog.qdisc;
+ enum hrtimer_restart ret = HRTIMER_NORESTART;
psched_time_t now;
psched_tdiff_t delay = 0;
unsigned pmask;
@@ -634,13 +635,14 @@ static enum hrtimer_restart cbq_undelay(
time = ktime_set(0, 0);
time = ktime_add_ns(time, PSCHED_TICKS2NS(now + delay));
- hrtimer_start(&q->delay_timer, time, HRTIMER_MODE_ABS);
+ hrtimer_set_expires(&q->delay_timer, time);
+ ret = HRTIMER_RESTART;
}
spin_unlock(&q->lock);
sch->flags &= ~TCQ_F_THROTTLED;
__netif_schedule(qdisc_root(sch));
- return HRTIMER_NORESTART;
+ return ret;
}
#ifdef CONFIG_NET_CLS_ACT
^ permalink raw reply
* [patch 2/3] net: sanitize hrtimer usage in sched_cbq
From: Thomas Gleixner @ 2009-07-09 21:59 UTC (permalink / raw)
To: netdev; +Cc: LKML, David Miller, Patrick McHardy, Peter Zijlstra
In-Reply-To: <20090709215455.703939259@linutronix.de>
[-- Attachment #1: net-sched-cbq-sanitize-hrtimer-usage.patch --]
[-- Type: text/plain, Size: 3134 bytes --]
The usage of hrtimer in cbq_ovl_delay() is less than obvious and in
two aspects wrong.
The intention of the code is to arm an hrtimer with the expiry time
X. If the timer is already armed the code needs to check whether the
expiry time X is earlier than the expiry time of the armed timer and
either keep the active timer or rearm it to X. If the timer is not
armed it needs to schedule it to X. That's not what the code does.
It calls hrtimer_try_to_cancel() unconditionally and checks the return
value. If the return value is non zero then it compares the expiry
time of the timer with the new expiry time and picks the earlier
one. The return value check does not take into account that the timer
might run its callback (expressed by a return value of -1). In that
case the expiry time of the timer is probably earlier than the new
expiry time so it rearms the already expired timer with the expiry
value in the past.
If the timer is not active (hrtimer_try_to_cancel() returns 0) it does
not set the new expiry time X but instead restarts the timer with the
expiry time which was active when the timer fired last. That's in the
past as well.
Change the code to check whether the timer is enqueued. If it is
enqueued then the expiry time of the timer is checked against the new
expiry time and it only calls hrtimer_start when the new expiry time
is earlier than the already armed timer. If the timer is not active
then arm it unconditionally with the new expiry time.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Patrick McHardy <kaber@trash.net>
---
net/sched/sch_cbq.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
Index: linux-2.6/net/sched/sch_cbq.c
===================================================================
--- linux-2.6.orig/net/sched/sch_cbq.c
+++ linux-2.6/net/sched/sch_cbq.c
@@ -494,7 +494,6 @@ static void cbq_ovl_delay(struct cbq_cla
if (!cl->delayed) {
psched_time_t sched = q->now;
- ktime_t expires;
delay += cl->offtime;
if (cl->avgidle < 0)
@@ -504,6 +503,7 @@ static void cbq_ovl_delay(struct cbq_cla
cl->undertime = q->now + delay;
if (delay > 0) {
+ ktime_t expires, actexp;
unsigned long flags;
spin_lock_irqsave(&q->lock, flags);
@@ -514,12 +514,19 @@ static void cbq_ovl_delay(struct cbq_cla
expires = ktime_set(0, 0);
expires = ktime_add_ns(expires, PSCHED_TICKS2NS(sched));
- if (hrtimer_try_to_cancel(&q->delay_timer) &&
- ktime_to_ns(ktime_sub(
- hrtimer_get_expires(&q->delay_timer),
- expires)) > 0)
- hrtimer_set_expires(&q->delay_timer, expires);
- hrtimer_restart(&q->delay_timer);
+ /*
+ * If the timer is queued check whether the
+ * new expiry time is earlier than the current
+ * one.
+ */
+ if (hrtimer_is_queued(&q->delay_timer)) {
+ actexp = hrtimer_get_expires(&q->delay_timer);
+ if (expires.tv64 >= actexp.tv64)
+ expires.tv64 = 0;
+ }
+ if (expires.tv64)
+ hrtimer_start(&q->delay_timer, expires,
+ HRTIMER_MODE_ABS);
cl->delayed = 1;
cl->xstats.overactions++;
spin_unlock_irqrestore(&q->lock, flags);
^ permalink raw reply
* [patch 1/3] net: serialize hrtimer callback in sched_cbq
From: Thomas Gleixner @ 2009-07-09 21:59 UTC (permalink / raw)
To: netdev; +Cc: LKML, David Miller, Patrick McHardy, Peter Zijlstra
In-Reply-To: <20090709215455.703939259@linutronix.de>
[-- Attachment #1: net-sched-cbq-serialize-hrtimer-callback.patch --]
[-- Type: text/plain, Size: 1956 bytes --]
The hrtimer callback cbq_undelay() is not serialized against
cbq_ovl_delay(). That affects at least q->pmask and q->delay_timer.
Lock it proper.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
net/sched/sch_cbq.c | 8 ++++++++
1 file changed, 8 insertions(+)
Index: linux-2.6/net/sched/sch_cbq.c
===================================================================
--- linux-2.6.orig/net/sched/sch_cbq.c
+++ linux-2.6/net/sched/sch_cbq.c
@@ -163,6 +163,7 @@ struct cbq_sched_data
psched_time_t now_rt; /* Cached real time */
unsigned pmask;
+ spinlock_t lock;
struct hrtimer delay_timer;
struct qdisc_watchdog watchdog; /* Watchdog timer,
started when CBQ has
@@ -503,6 +504,9 @@ static void cbq_ovl_delay(struct cbq_cla
cl->undertime = q->now + delay;
if (delay > 0) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&q->lock, flags);
sched += delay + cl->penalty;
cl->penalized = sched;
cl->cpriority = TC_CBQ_MAXPRIO;
@@ -518,6 +522,7 @@ static void cbq_ovl_delay(struct cbq_cla
hrtimer_restart(&q->delay_timer);
cl->delayed = 1;
cl->xstats.overactions++;
+ spin_unlock_irqrestore(&q->lock, flags);
return;
}
delay = 1;
@@ -599,6 +604,7 @@ static enum hrtimer_restart cbq_undelay(
now = psched_get_time();
+ spin_lock(&q->lock);
pmask = q->pmask;
q->pmask = 0;
@@ -623,6 +629,7 @@ static enum hrtimer_restart cbq_undelay(
time = ktime_add_ns(time, PSCHED_TICKS2NS(now + delay));
hrtimer_start(&q->delay_timer, time, HRTIMER_MODE_ABS);
}
+ spin_unlock(&q->lock);
sch->flags &= ~TCQ_F_THROTTLED;
__netif_schedule(qdisc_root(sch));
@@ -1396,6 +1403,7 @@ static int cbq_init(struct Qdisc *sch, s
q->link.avpkt = q->link.allot/2;
q->link.minidle = -0x7FFFFFFF;
+ spin_lock_init(&q->lock);
qdisc_watchdog_init(&q->watchdog, sch);
hrtimer_init(&q->delay_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
q->delay_timer.function = cbq_undelay;
^ permalink raw reply
* [patch 0/3] net: Sanitizing hrtimer usage in net/sched/sch_cbq.c
From: Thomas Gleixner @ 2009-07-09 21:59 UTC (permalink / raw)
To: netdev; +Cc: LKML, David Miller, Patrick McHardy, Peter Zijlstra
While looking at the "Soft-Lockup/Race in networking in 2.6.31-rc1+195
( possibly caused by netem)" issue (http://lkml.org/lkml/2009/7/2/519)
I noticed some serious problems in the hrtimer related code of
net/sched/sched/sch_cbq.c.
The following patch series addresses these.
I'm not entirely sure whether patch [1/3] covers all possible
concurrent modifications, but it fixes the most obvious ones. The
remaining details are left to the networking experts.
Patches [1/3] and [2/3] might be stable material as well.
Thanks,
tglx
^ permalink raw reply
* Re: [PATCH] don't touch bridge sysfs in container.
From: Stephen Hemminger @ 2009-07-09 21:23 UTC (permalink / raw)
To: Ken-ichirou MATSUZAWA; +Cc: Ken-ichirou MATSUZAWA, netdev
In-Reply-To: <877hyicf4x.wl%chamas@h4.dion.ne.jp>
On Thu, 09 Jul 2009 19:41:34 +0900
Ken-ichirou MATSUZAWA <chamas@h4.dion.ne.jp> wrote:
> Hello,
>
> At Wed, 8 Jul 2009 09:33:20 -0700,
> Stephen Hemminger wrote:
>
> > There is a per netns sysfs interface, it should be changed to use that.
>
> Sorry, I can see only:
>
> - add netns suffix was disagreed
> - tagged sysfs may not be merged
Without tagged sysfs, how could bridge interface work in other containers?
--
^ permalink raw reply
* Re: Soft-Lockup/Race in networking in 2.6.31-rc1+195 ( possibly?caused by netem)
From: Joao Correia @ 2009-07-09 21:19 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Andres Freund, Jarek Poplawski, Arun R Bharadwaj,
Stephen Hemminger, netdev, LKML, Patrick McHardy, Peter Zijlstra
In-Reply-To: <alpine.LFD.2.00.0907091943290.2768@localhost.localdomain>
On Thu, Jul 9, 2009 at 6:44 PM, Thomas Gleixner<tglx@linutronix.de> wrote:
> Andres,
>
> On Thu, 9 Jul 2009, Andres Freund wrote:
>
>> On Thursday 09 July 2009 18:01:56 Thomas Gleixner wrote:
>> > Andres,
>> >
>> > On Thu, 9 Jul 2009, Andres Freund wrote:
>> > > On Thursday 09 July 2009 16:28:05 Thomas Gleixner wrote:
>> > > > Please test them separate from each other. The one I sent in this
>> > > > thread was just for narrowing down the issue, but I'm now quite sure
>> > > > that they really hit the issue which is addressed by the hrtimer
>> > > > patch.
>> > >
>> > > No crash yet. 15min running (seconds to a minute before).
>> > >
>> > > Will let it run for some hours to be sure.
>> >
>> > Which one of the patches are you testing ?
>> Your "real" one, i.e. de907e8432b08f2d5966c36e0747e97c0e596810
>>
>> 1h30m now...
>
> Looks like I hit the nail on the head. Queueing it up for Linus.
>
> Thanks,
>
> tglx
>
Confirmed working from me as well.
Thank you for your time,
Joao Correia
^ permalink raw reply
* Re: [PATCH for 2.6.31] cxgb3: Fix crash caused by stashing wrong netdev_queue
From: Divy Le Ray @ 2009-07-09 21:15 UTC (permalink / raw)
To: Roland Dreier; +Cc: David S. Miller, netdev
In-Reply-To: <adabpnty7qm.fsf_-_@cisco.com>
Roland Dreier wrote:
> Commit c3a8c5b6 ("cxgb3: move away from LLTX") exposed a bug in how
> cxgb3 looks up the netdev_queue it stashes away in a qset during
> initialization. For multiport devices, the TX queue index it uses is
> offset by the first_qset index of each port. This leads to a crash
> once LLTX is removed, since hard_start_xmit is called with one TX
> queue lock held, while the TX reclaim timer task grabs a different
> (wrong) TX queue lock when it frees skbs.
>
> Fix this by removing the first_qset offset used to look up the TX
> queue passed into t3_sge_alloc_qset() from setup_sge_qsets().
>
Thanks Roland!
You were very fast to fix it, you beat us.
Acked-by: Divy Le Ray <divy@chelsio.com>
> Signed-off-by: Roland Dreier <rolandd@cisco.com>
> ---
> OK, found the bug that was causing the crash I saw. With this patch
> everything looks solid again. Please apply.
>
> drivers/net/cxgb3/cxgb3_main.c | 3 +--
> 1 files changed, 1 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
> index 538dda4..fb5df5c 100644
> --- a/drivers/net/cxgb3/cxgb3_main.c
> +++ b/drivers/net/cxgb3/cxgb3_main.c
> @@ -642,8 +642,7 @@ static int setup_sge_qsets(struct adapter *adap)
> struct port_info *pi = netdev_priv(dev);
>
> pi->qs = &adap->sge.qs[pi->first_qset];
> - for (j = pi->first_qset; j < pi->first_qset + pi->nqsets;
> - ++j, ++qset_idx) {
> + for (j = 0; j < pi->nqsets; ++j, ++qset_idx) {
> set_qset_lro(dev, qset_idx, pi->rx_offload & T3_LRO);
> err = t3_sge_alloc_qset(adap, qset_idx, 1,
> (adap->flags & USING_MSIX) ? qset_idx + 1 :
>
^ permalink raw reply
* Re: include/linux/mii.h licence?
From: Stephen Hemminger @ 2009-07-09 21:13 UTC (permalink / raw)
To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: David Miller, netdev
In-Reply-To: <20090709205407.GP28344@game.jcrosoft.org>
On Thu, 9 Jul 2009 22:54:07 +0200
Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> wrote:
> Hi David,
>
> what is the licence of the include/linux/mii.h file?
> GPLv2 or GPLv2+
>
> Best Regards,
> J.
> --
> 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
Consensus is that files without individual license are covered by overall
Linux GPLv2 defined in COPYING in top level directory; but IANAL.
--
^ permalink raw reply
* include/linux/mii.h licence?
From: Jean-Christophe PLAGNIOL-VILLARD @ 2009-07-09 20:54 UTC (permalink / raw)
To: David Miller; +Cc: netdev
Hi David,
what is the licence of the include/linux/mii.h file?
GPLv2 or GPLv2+
Best Regards,
J.
^ permalink raw reply
* Re: [PATCH] net: sk_prot_alloc() should not blindly overwrite memory
From: Eric Dumazet @ 2009-07-09 20:50 UTC (permalink / raw)
To: paulmck
Cc: David Miller, emil.s.tantilov, emils.tantilov, netdev,
jesse.brandeburg, jeffrey.t.kirsher, jolsa, Patrick McHardy
In-Reply-To: <20090709171328.GB6723@linux.vnet.ibm.com>
Paul E. McKenney a écrit :
> On Thu, Jul 09, 2009 at 07:36:05AM +0200, Eric Dumazet wrote:
>> Eric Dumazet a écrit :
>>> David Miller a écrit :
>>>> From: Eric Dumazet <eric.dumazet@gmail.com>
>>>> Date: Wed, 08 Jul 2009 00:33:29 +0200
>>>>
>>>>> [PATCH] net: sk_prot_alloc() should not blindly overwrite memory
>>>>>
>>>>> Some sockets use SLAB_DESTROY_BY_RCU, and our RCU code rely that some
>>>>> fields should not be blindly overwritten, even with null.
>>>>>
>>>>> These fields are sk->sk_refcnt and sk->sk_nulls_node.next
>>>>>
>>>>> Current sk_prot_alloc() implementation doesnt respect this hypothesis,
>>>>> calling kmem_cache_alloc() with __GFP_ZERO and setting sk_refcnt to 1
>>>>> instead of atomically increment it.
>>>>>
>>>>> Reported-by: Emil S Tantilov <emils.tantilov@gmail.com>
>>>>> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
>>>> I've applied this but will wait for some more testing before
>>>> I push it out for real to kernel.org
>>> Thanks David
>>>
>>> I forgot to CC Paul and Patrick, so I'll ask them to look at this patch.
>>>
>>> Patrick, a similar fix is needed in conntrack as well, we currently
>>> uses "ct = kmem_cache_zalloc(nf_conntrack_cachep, gfp);" and thus
>>> overwrite struct hlist_nulls_node hnnode; contained
>>> in "struct nf_conntrack_tuple_hash", while lockless readers still
>>> potentialy need them. Setting hnnode.next to NULL is dangerous
>>> since last bit is not set (not a nulls value), a reader could
>>> try to dereference this NULL pointer and trap.
>>>
>>>
>>> Here is the patch again so that Paul & Patrick can comment on it.
>>>
>>> I am not sure about the refcnt thing (blindly setting it to 0 again
>>> should be OK in fact, since no reader should/can to the
>>> atomic_inc_if_not_zero on it), but the nulls.next thing is problematic.
>> Here is an updated and much simpler patch, taking care of sk_node.next being not set to 0
>>
>> This patch applies to >= 2.6.29 kernels
>
> Does this one also need the rearrangement of struct elements in the
> earlier patch? (And apologies about being slow to get to that one.)
>
No, because only one field (sk_node.next) needs special attention, I felt
it was not really necessary to reorder fields. First memset
is inlined because of constant size, so small cost.
Thanks
> Thanx, Paul
>
>> [PATCH] net: sk_prot_alloc() should not blindly overwrite memory
>>
>> Some sockets use SLAB_DESTROY_BY_RCU, and our RCU code correctness
>> depends on sk->sk_nulls_node.next being always valid. A NULL
>> value is not allowed as it might fault a lockless reader.
>>
>> Current sk_prot_alloc() implementation doesnt respect this hypothesis,
>> calling kmem_cache_alloc() with __GFP_ZERO. Just call memset() around
>> the forbidden field.
>>
>> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
>> ---
>> diff --git a/net/core/sock.c b/net/core/sock.c
>> index b0ba569..7b87ec0 100644
>> --- a/net/core/sock.c
>> +++ b/net/core/sock.c
>> @@ -939,8 +939,23 @@ static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority,
>> struct kmem_cache *slab;
>>
>> slab = prot->slab;
>> - if (slab != NULL)
>> - sk = kmem_cache_alloc(slab, priority);
>> + if (slab != NULL) {
>> + sk = kmem_cache_alloc(slab, priority & ~__GFP_ZERO);
>> + if (!sk)
>> + return sk;
>> + if (priority & __GFP_ZERO) {
>> + /*
>> + * caches using SLAB_DESTROY_BY_RCU should let
>> + * sk_node.next un-modified. Special care is taken
>> + * when initializing object to zero.
>> + */
>> + if (offsetof(struct sock, sk_node.next) != 0)
>> + memset(sk, 0, offsetof(struct sock, sk_node.next));
>> + memset(&sk->sk_node.pprev, 0,
>> + prot->obj_size - offsetof(struct sock,
>> + sk_node.pprev));
>> + }
>> + }
>> else
>> sk = kmalloc(prot->obj_size, priority);
>>
^ permalink raw reply
* Re: [patch 2/2] net, netns_xt: shrink netns_xt members
From: Stephen Hemminger @ 2009-07-09 19:55 UTC (permalink / raw)
To: Cyrill Gorcunov; +Cc: kaber, bridge, netdev, Cyrill Gorcunov
In-Reply-To: <20090704062321.034802084@openvz.org>
On Sat, 04 Jul 2009 10:11:58 +0400
Cyrill Gorcunov <gorcunov@openvz.org> wrote:
> In case if kernel was compiled without ebtables support
> there is no need to keep ebt_table pointers in netns_xt
> structure.
>
> Make it config dependent.
>
> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
> ---
>
> Probably GCC will authomatically shrink the structure
> if the members are not in use. Please review.
>
> include/net/netns/x_tables.h | 3 +++
> 1 file changed, 3 insertions(+)
>
> Index: linux-2.6.git/include/net/netns/x_tables.h
> =====================================================================
> --- linux-2.6.git.orig/include/net/netns/x_tables.h
> +++ linux-2.6.git/include/net/netns/x_tables.h
> @@ -8,8 +8,11 @@ struct ebt_table;
>
> struct netns_xt {
> struct list_head tables[NFPROTO_NUMPROTO];
> +#if defined(CONFIG_BRIDGE_NF_EBTABLES) || \
> + defined(CONFIG_BRIDGE_NF_EBTABLES_MODULE)
> struct ebt_table *broute_table;
> struct ebt_table *frame_filter;
> struct ebt_table *frame_nat;
> +#endif
> };
> #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
Acked-by: Stephen Hemminger <shemminger@vyatta.com>
--
^ permalink raw reply
* Re: [patch 1/2] net, bridge: align br_nf_ops assignment
From: Stephen Hemminger @ 2009-07-09 19:55 UTC (permalink / raw)
To: Cyrill Gorcunov; +Cc: bridge, netdev, David Miller
In-Reply-To: <20090704062320.774818680@openvz.org>
On Sat, 04 Jul 2009 10:11:57 +0400
Cyrill Gorcunov <gorcunov@openvz.org> wrote:
> No functional change -- just for easier reading.
>
> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
> ---
> net/bridge/br_netfilter.c | 96 ++++++++++++++++++++++++++--------------------
> 1 file changed, 56 insertions(+), 40 deletions(-)
>
Acked-by: Stephen Hemminger <shemminger@vyatta.com>
--
^ permalink raw reply
* Re: [PATCH net-2.6] Re: rib_trie / Fix inflate_threshold_root. Now=15 size=11 bits
From: Paweł Staszewski @ 2009-07-09 20:34 UTC (permalink / raw)
To: Jarek Poplawski
Cc: Paul E. McKenney, Linux Network Development list, Robert Olsson
In-Reply-To: <20090707235029.GA8207@ami.dom.local>
Jarek Poplawski pisze:
> On Wed, Jul 08, 2009 at 12:56:13AM +0200, Paweł Staszewski wrote:
>
>> Jarek Poplawski pisze:
>>
> ...
>
>>> ---> (synchronize take 9; apply on top of the 2.6.29.x with the last
>>> all-in-one patch, or net-2.6)
>>>
>>>
>>>
>> Applied to 2.6.29.5 preempt/no-preempt and tested: - with preempt i make
>> only one test with sync_pages = 256 to check that is working :)
>>
>> So here are some tests for different sync_pages size.
>>
> ...
>
>> So i see in prev tests i make something wrong in time counting
>> So i modify test script and make tests again:
>>
>> echo 64 > /sys/module/fib_trie/parameters/sync_pages
>> Total size reach max in 13 sec
>>
>> echo 128 > /sys/module/fib_trie/parameters/sync_pages
>> Total size reach max in 10 sec
>>
>> echo 256 > /sys/module/fib_trie/parameters/sync_pages
>> Total size reach max in 10 sec
>>
>> And for sync_paqges >256 time for propagating routes is always 10sec.
>>
>
> So this means sync_pages 128 or 256 is reasonable.
>
>
>> Also today i have many messages in dmesg like this:
>> Fix inflate_threshold_root. Now=25 size=11 bits
>> :)
>>
>
>
> This is something new and a bit surprising to me: the same threshold
> in previous tests didn't generate this? Do you mean more than:
> "Fix inflate_threshold_root. Now=15 size=11 bits" before?
>
>
Yes. Sorry for that - this info was not all the day but only 5 minutes
when i was making tests.
This info was reported only when all iBGP peers was down/up fast.
>> And after tune :
>> /sys/module/fib_trie/parameters/inflate_threshold_root
>> no more info :)
>>
>
> With what value?
>
>
When i set 35 as inflate_threshold_root there was no info even if all
iBGP peers was down/up.
But i start to search when i have info about "Fix inflate_threshold_root"
And i see that the best is set this to 20 for me i have no info then in
normal router operation / without down/up bgp peers many times in short
time.
> Pawel, let's say that current defaults are:
> inflate_threshold_root 25 sync_pages 256
>
> I'd like you to try to check if e.g.:
> inflate_threshold_root 15 sync_pages 256
> can give you any visible or subjective difference worth tweaking it
> at all? (These stats from the next messages don't show this enough.)
> You don't need to hurry with this...
>
>
I will try to make more accurate tests in weekend.
Regards
Paweł Staszewski
> Thanks,
> Jarek P.
>
>
>
^ permalink raw reply
* [PATCH for 2.6.31] cxgb3: Fix crash caused by stashing wrong netdev_queue
From: Roland Dreier @ 2009-07-09 19:30 UTC (permalink / raw)
To: Divy Le Ray, David S. Miller; +Cc: netdev
In-Reply-To: <4A554A1D.3070703@chelsio.com>
Commit c3a8c5b6 ("cxgb3: move away from LLTX") exposed a bug in how
cxgb3 looks up the netdev_queue it stashes away in a qset during
initialization. For multiport devices, the TX queue index it uses is
offset by the first_qset index of each port. This leads to a crash
once LLTX is removed, since hard_start_xmit is called with one TX
queue lock held, while the TX reclaim timer task grabs a different
(wrong) TX queue lock when it frees skbs.
Fix this by removing the first_qset offset used to look up the TX
queue passed into t3_sge_alloc_qset() from setup_sge_qsets().
Signed-off-by: Roland Dreier <rolandd@cisco.com>
---
OK, found the bug that was causing the crash I saw. With this patch
everything looks solid again. Please apply.
drivers/net/cxgb3/cxgb3_main.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 538dda4..fb5df5c 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -642,8 +642,7 @@ static int setup_sge_qsets(struct adapter *adap)
struct port_info *pi = netdev_priv(dev);
pi->qs = &adap->sge.qs[pi->first_qset];
- for (j = pi->first_qset; j < pi->first_qset + pi->nqsets;
- ++j, ++qset_idx) {
+ for (j = 0; j < pi->nqsets; ++j, ++qset_idx) {
set_qset_lro(dev, qset_idx, pi->rx_offload & T3_LRO);
err = t3_sge_alloc_qset(adap, qset_idx, 1,
(adap->flags & USING_MSIX) ? qset_idx + 1 :
^ permalink raw reply related
* [PATCH net-next-2.6 5/5] udpv6: Handle large incoming UDP/IPv6 packets and support software UFO
From: Sridhar Samudrala @ 2009-07-09 18:10 UTC (permalink / raw)
To: David Miller, Herbert Xu, netdev
[PATCH net-next-2.6 5/5] udpv6: Handle large incoming UDP/IPv6 packets and support software UFO
- validate and forward GSO UDP/IPv6 packets from untrusted sources.
- do software UFO if the outgoing device doesn't support UFO.
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
---
net/ipv6/af_inet6.c | 20 +++++++++--
net/ipv6/udp.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 110 insertions(+), 3 deletions(-)
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index caa0278..bf85d5f 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -772,6 +772,11 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, int features)
struct sk_buff *segs = ERR_PTR(-EINVAL);
struct ipv6hdr *ipv6h;
struct inet6_protocol *ops;
+ int proto;
+ struct frag_hdr *fptr;
+ unsigned int unfrag_ip6hlen;
+ u8 *prevhdr;
+ int offset = 0;
if (!(features & NETIF_F_V6_CSUM))
features &= ~NETIF_F_SG;
@@ -791,10 +796,9 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, int features)
__skb_pull(skb, sizeof(*ipv6h));
segs = ERR_PTR(-EPROTONOSUPPORT);
+ proto = ipv6_gso_pull_exthdrs(skb, ipv6h->nexthdr);
rcu_read_lock();
- ops = rcu_dereference(inet6_protos[
- ipv6_gso_pull_exthdrs(skb, ipv6h->nexthdr)]);
-
+ ops = rcu_dereference(inet6_protos[proto]);
if (likely(ops && ops->gso_segment)) {
skb_reset_transport_header(skb);
segs = ops->gso_segment(skb, features);
@@ -808,6 +812,16 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, int features)
ipv6h = ipv6_hdr(skb);
ipv6h->payload_len = htons(skb->len - skb->mac_len -
sizeof(*ipv6h));
+ if (proto == IPPROTO_UDP) {
+ unfrag_ip6hlen = ip6_find_1stfragopt(skb, &prevhdr);
+ fptr = (struct frag_hdr *)(skb_network_header(skb) +
+ unfrag_ip6hlen);
+ fptr->frag_off = htons(offset);
+ if (skb->next != NULL)
+ fptr->frag_off |= htons(IP6_MF);
+ offset += (ntohs(ipv6h->payload_len) -
+ sizeof(struct frag_hdr));
+ }
}
out:
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index f31b1b9..d79fa67 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1078,9 +1078,102 @@ int compat_udpv6_getsockopt(struct sock *sk, int level, int optname,
}
#endif
+static int udp6_ufo_send_check(struct sk_buff *skb)
+{
+ struct ipv6hdr *ipv6h;
+ struct udphdr *uh;
+
+ if (!pskb_may_pull(skb, sizeof(*uh)))
+ return -EINVAL;
+
+ ipv6h = ipv6_hdr(skb);
+ uh = udp_hdr(skb);
+
+ uh->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, skb->len,
+ IPPROTO_UDP, 0);
+ skb->csum_start = skb_transport_header(skb) - skb->head;
+ skb->csum_offset = offsetof(struct udphdr, check);
+ skb->ip_summed = CHECKSUM_PARTIAL;
+ return 0;
+}
+
+static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, int features)
+{
+ struct sk_buff *segs = ERR_PTR(-EINVAL);
+ unsigned int mss;
+ unsigned int unfrag_ip6hlen, unfrag_len;
+ struct frag_hdr *fptr;
+ u8 *mac_start, *prevhdr;
+ u8 nexthdr;
+ u8 frag_hdr_sz = sizeof(struct frag_hdr);
+ int offset;
+ __wsum csum;
+
+ mss = skb_shinfo(skb)->gso_size;
+ if (unlikely(skb->len <= mss))
+ goto out;
+
+ if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) {
+ /* Packet is from an untrusted source, reset gso_segs. */
+ int type = skb_shinfo(skb)->gso_type;
+
+ if (unlikely(type & ~(SKB_GSO_UDP | SKB_GSO_DODGY) ||
+ !(type & (SKB_GSO_UDP))))
+ goto out;
+
+ skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(skb->len, mss);
+
+ segs = NULL;
+ goto out;
+ }
+
+ /* Do software UFO. Complete and fill in the UDP checksum as HW cannot
+ * do checksum of UDP packets sent as multiple IP fragments.
+ */
+ offset = skb->csum_start - skb_headroom(skb);
+ csum = skb_checksum(skb, offset, skb->len- offset, 0);
+ offset += skb->csum_offset;
+ *(__sum16 *)(skb->data + offset) = csum_fold(csum);
+ skb->ip_summed = CHECKSUM_NONE;
+
+ /* Check if there is enough headroom to insert fragment header. */
+ if ((skb_headroom(skb) < frag_hdr_sz) &&
+ pskb_expand_head(skb, frag_hdr_sz, 0, GFP_ATOMIC))
+ goto out;
+
+ /* Find the unfragmentable header and shift it left by frag_hdr_sz
+ * bytes to insert fragment header.
+ */
+ unfrag_ip6hlen = ip6_find_1stfragopt(skb, &prevhdr);
+ nexthdr = *prevhdr;
+ *prevhdr = NEXTHDR_FRAGMENT;
+ unfrag_len = skb_network_header(skb) - skb_mac_header(skb) +
+ unfrag_ip6hlen;
+ mac_start = skb_mac_header(skb);
+ memmove(mac_start-frag_hdr_sz, mac_start, unfrag_len);
+
+ skb->mac_header -= frag_hdr_sz;
+ skb->network_header -= frag_hdr_sz;
+
+ fptr = (struct frag_hdr *)(skb_network_header(skb) + unfrag_ip6hlen);
+ fptr->nexthdr = nexthdr;
+ fptr->reserved = 0;
+ ipv6_select_ident(fptr);
+
+ /* Fragment the skb. ipv6 header and the remaining fields of the
+ * fragment header are updated in ipv6_gso_segment()
+ */
+ segs = skb_segment(skb, features);
+
+out:
+ return segs;
+}
+
static struct inet6_protocol udpv6_protocol = {
.handler = udpv6_rcv,
.err_handler = udpv6_err,
+ .gso_send_check = udp6_ufo_send_check,
+ .gso_segment = udp6_ufo_fragment,
.flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
};
^ permalink raw reply related
* [PATCH net-next-2.6 4/5] udpv6: Remove unused skb argument of ipv6_select_ident()
From: Sridhar Samudrala @ 2009-07-09 18:10 UTC (permalink / raw)
To: David Miller, Herbert Xu, netdev
[PATCH net-next-2.6 4/5] udpv6: Remove unused skb argument of ipv6_select_ident()
- move ipv6_select_ident() inline function to ipv6.h and remove the unused
skb argument
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
---
include/net/ipv6.h | 12 ++++++++++++
net/ipv6/ip6_output.c | 18 +++---------------
2 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index f27fd83..ad9a511 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -441,6 +441,18 @@ static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_add
return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr));
}
+static __inline__ void ipv6_select_ident(struct frag_hdr *fhdr)
+{
+ static u32 ipv6_fragmentation_id = 1;
+ static DEFINE_SPINLOCK(ip6_id_lock);
+
+ spin_lock_bh(&ip6_id_lock);
+ fhdr->identification = htonl(ipv6_fragmentation_id);
+ if (++ipv6_fragmentation_id == 0)
+ ipv6_fragmentation_id = 1;
+ spin_unlock_bh(&ip6_id_lock);
+}
+
/*
* Prototypes exported by ipv6
*/
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 1c6f0fc..dd1a980 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -57,18 +57,6 @@
static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));
-static __inline__ void ipv6_select_ident(struct sk_buff *skb, struct frag_hdr *fhdr)
-{
- static u32 ipv6_fragmentation_id = 1;
- static DEFINE_SPINLOCK(ip6_id_lock);
-
- spin_lock_bh(&ip6_id_lock);
- fhdr->identification = htonl(ipv6_fragmentation_id);
- if (++ipv6_fragmentation_id == 0)
- ipv6_fragmentation_id = 1;
- spin_unlock_bh(&ip6_id_lock);
-}
-
int __ip6_local_out(struct sk_buff *skb)
{
int len;
@@ -706,7 +694,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
skb_reset_network_header(skb);
memcpy(skb_network_header(skb), tmp_hdr, hlen);
- ipv6_select_ident(skb, fh);
+ ipv6_select_ident(fh);
fh->nexthdr = nexthdr;
fh->reserved = 0;
fh->frag_off = htons(IP6_MF);
@@ -844,7 +832,7 @@ slow_path:
fh->nexthdr = nexthdr;
fh->reserved = 0;
if (!frag_id) {
- ipv6_select_ident(skb, fh);
+ ipv6_select_ident(fh);
frag_id = fh->identification;
} else
fh->identification = frag_id;
@@ -1093,7 +1081,7 @@ static inline int ip6_ufo_append_data(struct sock *sk,
skb_shinfo(skb)->gso_size = (mtu - fragheaderlen -
sizeof(struct frag_hdr)) & ~7;
skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
- ipv6_select_ident(skb, &fhdr);
+ ipv6_select_ident(&fhdr);
skb_shinfo(skb)->ip6_frag_id = fhdr.identification;
__skb_queue_tail(&sk->sk_write_queue, skb);
^ permalink raw reply related
* [PATCH net-next-2.6 3/5] udpv6: Fix gso_size setting in ip6_ufo_append_data
From: Sridhar Samudrala @ 2009-07-09 18:09 UTC (permalink / raw)
To: David Miller, Herbert Xu, netdev
[PATCH net-next-2.6 3/5] udpv6: Fix gso_size setting in ip6_ufo_append_data
- fix gso_size setting for ipv6 fragment to be a multiple of 8 bytes.
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
---
net/ipv6/ip6_output.c | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 7c76e3d..1c6f0fc 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1087,9 +1087,11 @@ static inline int ip6_ufo_append_data(struct sock *sk,
if (!err) {
struct frag_hdr fhdr;
- /* specify the length of each IP datagram fragment*/
- skb_shinfo(skb)->gso_size = mtu - fragheaderlen -
- sizeof(struct frag_hdr);
+ /* Specify the length of each IPv6 datagram fragment.
+ * It has to be a multiple of 8.
+ */
+ skb_shinfo(skb)->gso_size = (mtu - fragheaderlen -
+ sizeof(struct frag_hdr)) & ~7;
skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
ipv6_select_ident(skb, &fhdr);
skb_shinfo(skb)->ip6_frag_id = fhdr.identification;
^ permalink raw reply related
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