Netdev List
 help / color / mirror / Atom feed
* 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


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