Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH next 5/6] bonding: Allow userspace to set macaddr on bonding-dev
From: Mahesh Bandewar @ 2015-02-07  2:41 UTC (permalink / raw)
  To: Jay Vosburgh
  Cc: Andy Gospodarek, Veaceslav Falico, Nikolay Aleksandrov,
	David Miller, netdev, Eric Dumazet, Maciej Żenczykowski
In-Reply-To: <4653.1423274042@famine>

On Fri, Feb 6, 2015 at 5:54 PM, Jay Vosburgh <jay.vosburgh@canonical.com> wrote:
> Mahesh Bandewar <maheshb@google.com> wrote:
>
>>On Fri, Feb 6, 2015 at 5:20 PM, Jay Vosburgh <jay.vosburgh@canonical.com> wrote:
>>> Mahesh Bandewar <maheshb@google.com> wrote:
>>>
>>>>This patch allows user-space to set the mac-address on the bonding device.
>>>>This mac-address can not be NULL or a Multicast. If the mac-address is set
>>>>from user-space; kernel will honor it and will not overwrite it. In the
>>>>absense (value from user space); the logic will default to using the
>>>>masters' mac as the mac address for the bonding device.
>>>>
>>>>It can be set using example code below -
>>>>
>>>>   # modprobe bonding mode=4
>>>>   # sys_mac_addr=$(printf '%02x:%02x:%02x:%02x:%02x:%02x' \
>>>>                    $(( (RANDOM & 0xFE) | 0x02 )) \
>>>>                    $(( RANDOM & 0xFF )) \
>>>>                    $(( RANDOM & 0xFF )) \
>>>>                    $(( RANDOM & 0xFF )) \
>>>>                    $(( RANDOM & 0xFF )) \
>>>>                    $(( RANDOM & 0xFF )))
>>>>   # echo $sys_mac_addr > /sys/class/net/bond0/bonding/ad_actor_system_mac_address
>>>>   # echo +eth1 > /sys/class/net/bond0/bonding/slaves
>>>>   ...
>>>>   # ip link set bond0 up
>>>
>>>         How is this patch functionally different from setting the
>>> bonding master's MAC address to a particular value prior to adding any
>>> slaves?
>>>
>>
>>Maciej is correct but I think I was bit ambiguous about it in the
>>commit message which might have made you think this way. I'll reword
>>the commit message.
>
>         Thanks; presumably there is some administrative reason for this.
>
The idea is that in an AD system the actor-partner communication is a
business between them two only and no one in the L2 domain should
care. These enhancements should obscure that should anyone try to
sniff it. Probably I assumed too much and should add this idea behind
the implementation in the commit log.

>         Also, for patches 4, 5 and 6, I believe current practice is to
> provide a netlink / iproute2 facility for options.
>
OK. I'll add them (netlink enhancements) in a separate set of patch(s).

>         -J
>
>
>>>         -J
>>>
>>>>Signed-off-by: Mahesh Bandewar <maheshb@google.com>
>>>>---
>>>> drivers/net/bonding/bond_3ad.c     |  7 ++++++-
>>>> drivers/net/bonding/bond_main.c    |  1 +
>>>> drivers/net/bonding/bond_options.c | 29 +++++++++++++++++++++++++++++
>>>> drivers/net/bonding/bond_procfs.c  |  6 ++++++
>>>> drivers/net/bonding/bond_sysfs.c   | 16 ++++++++++++++++
>>>> include/net/bond_options.h         |  1 +
>>>> include/net/bonding.h              |  1 +
>>>> 7 files changed, 60 insertions(+), 1 deletion(-)
>>>>
>>>>diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
>>>>index 1177f96194dd..373d3db3809f 100644
>>>>--- a/drivers/net/bonding/bond_3ad.c
>>>>+++ b/drivers/net/bonding/bond_3ad.c
>>>>@@ -1914,7 +1914,12 @@ void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution)
>>>>
>>>>               BOND_AD_INFO(bond).system.sys_priority =
>>>>                       bond->params.ad_actor_sysprio;
>>>>-              BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->dev->dev_addr);
>>>>+              if (is_zero_ether_addr(bond->params.ad_actor_sys_macaddr))
>>>>+                      BOND_AD_INFO(bond).system.sys_mac_addr =
>>>>+                          *((struct mac_addr *)bond->dev->dev_addr);
>>>>+              else
>>>>+                      BOND_AD_INFO(bond).system.sys_mac_addr =
>>>>+                          *((struct mac_addr *)bond->params.ad_actor_sys_macaddr);
>>>>
>>>>               /* initialize how many times this module is called in one
>>>>                * second (should be about every 100ms)
>>>>diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
>>>>index 561b2bde5aeb..1a6735ef2ea7 100644
>>>>--- a/drivers/net/bonding/bond_main.c
>>>>+++ b/drivers/net/bonding/bond_main.c
>>>>@@ -4440,6 +4440,7 @@ static int bond_check_params(struct bond_params *params)
>>>>       params->packets_per_slave = packets_per_slave;
>>>>       params->tlb_dynamic_lb = 1; /* Default value */
>>>>       params->ad_actor_sysprio = ad_actor_sysprio;
>>>>+      eth_zero_addr(params->ad_actor_sys_macaddr);
>>>>       if (packets_per_slave > 0) {
>>>>               params->reciprocal_packets_per_slave =
>>>>                       reciprocal_value(packets_per_slave);
>>>>diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
>>>>index d8f6760143ae..330d48b6a1e6 100644
>>>>--- a/drivers/net/bonding/bond_options.c
>>>>+++ b/drivers/net/bonding/bond_options.c
>>>>@@ -72,6 +72,8 @@ static int bond_option_tlb_dynamic_lb_set(struct bonding *bond,
>>>>                                 const struct bond_opt_value *newval);
>>>> static int bond_option_ad_actor_sysprio_set(struct bonding *bond,
>>>>                                 const struct bond_opt_value *newval);
>>>>+static int bond_option_ad_actor_sys_macaddr_set(struct bonding *bond,
>>>>+                                const struct bond_opt_value *newval);
>>>>
>>>>
>>>> static const struct bond_opt_value bond_mode_tbl[] = {
>>>>@@ -396,6 +398,13 @@ static const struct bond_option bond_opts[BOND_OPT_LAST] = {
>>>>               .values = bond_ad_actor_sysprio_tbl,
>>>>               .set = bond_option_ad_actor_sysprio_set,
>>>>       },
>>>>+      [BOND_OPT_AD_ACTOR_SYS_MACADDR] = {
>>>>+              .id = BOND_OPT_AD_ACTOR_SYS_MACADDR,
>>>>+              .name = "ad_actor_system_mac_address",
>>>>+              .unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_8023AD)),
>>>>+              .flags = BOND_OPTFLAG_RAWVAL | BOND_OPTFLAG_IFDOWN,
>>>>+              .set = bond_option_ad_actor_sys_macaddr_set,
>>>>+      },
>>>> };
>>>>
>>>> /* Searches for an option by name */
>>>>@@ -1376,3 +1385,23 @@ static int bond_option_ad_actor_sysprio_set(struct bonding *bond,
>>>>       bond->params.ad_actor_sysprio = newval->value;
>>>>       return 0;
>>>> }
>>>>+
>>>>+static int bond_option_ad_actor_sys_macaddr_set(struct bonding *bond,
>>>>+                                          const struct bond_opt_value *newval)
>>>>+{
>>>>+      u8 macaddr[ETH_ALEN];
>>>>+      int i;
>>>>+
>>>>+      i = sscanf(newval->string, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
>>>>+                 &macaddr[0], &macaddr[1], &macaddr[2],
>>>>+                 &macaddr[3], &macaddr[4], &macaddr[5]);
>>>>+
>>>>+      if (i != ETH_ALEN || !is_valid_ether_addr(macaddr)) {
>>>>+              netdev_err(bond->dev, "Invalid MAC address.\n");
>>>>+              return -EINVAL;
>>>>+      }
>>>>+
>>>>+      ether_addr_copy(bond->params.ad_actor_sys_macaddr, macaddr);
>>>>+
>>>>+      return 0;
>>>>+}
>>>>diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c
>>>>index 9e33c48886ef..81452ced852f 100644
>>>>--- a/drivers/net/bonding/bond_procfs.c
>>>>+++ b/drivers/net/bonding/bond_procfs.c
>>>>@@ -136,6 +136,8 @@ static void bond_info_show_master(struct seq_file *seq)
>>>>                          optval->string);
>>>>               seq_printf(seq, "System priority: %d\n",
>>>>                               BOND_AD_INFO(bond).system.sys_priority);
>>>>+              seq_printf(seq, "System MAC address: %pM\n",
>>>>+                              &BOND_AD_INFO(bond).system.sys_mac_addr);
>>>>
>>>>               if (__bond_3ad_get_active_agg_info(bond, &ad_info)) {
>>>>                       seq_printf(seq, "bond %s has no active aggregator\n",
>>>>@@ -198,6 +200,8 @@ static void bond_info_show_slave(struct seq_file *seq,
>>>>                       seq_puts(seq, "details actor lacp pdu:\n");
>>>>                       seq_printf(seq, "    system priority: %d\n",
>>>>                                  port->actor_system_priority);
>>>>+                      seq_printf(seq, "    system mac address: %pM\n",
>>>>+                                 &port->actor_system);
>>>>                       seq_printf(seq, "    port key: %d\n",
>>>>                                  port->actor_oper_port_key);
>>>>                       seq_printf(seq, "    port priority: %d\n",
>>>>@@ -210,6 +214,8 @@ static void bond_info_show_slave(struct seq_file *seq,
>>>>                       seq_puts(seq, "details partner lacp pdu:\n");
>>>>                       seq_printf(seq, "    system priority: %d\n",
>>>>                                  port->partner_oper.system_priority);
>>>>+                      seq_printf(seq, "    system mac address: %pM\n",
>>>>+                                 &port->partner_oper.system);
>>>>                       seq_printf(seq, "    oper key: %d\n",
>>>>                                  port->partner_oper.key);
>>>>                       seq_printf(seq, "    port priority: %d\n",
>>>>diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
>>>>index 4350aa06f867..91713d0b6685 100644
>>>>--- a/drivers/net/bonding/bond_sysfs.c
>>>>+++ b/drivers/net/bonding/bond_sysfs.c
>>>>@@ -706,6 +706,21 @@ static ssize_t bonding_show_ad_actor_sysprio(struct device *d,
>>>> static DEVICE_ATTR(ad_actor_system_priority, S_IRUGO | S_IWUSR,
>>>>                  bonding_show_ad_actor_sysprio, bonding_sysfs_store_option);
>>>>
>>>>+static ssize_t bonding_show_ad_actor_sys_macaddr(struct device *d,
>>>>+                                               struct device_attribute *attr,
>>>>+                                               char *buf)
>>>>+{
>>>>+      struct bonding *bond = to_bond(d);
>>>>+
>>>>+      if (BOND_MODE(bond) == BOND_MODE_8023AD)
>>>>+              return sprintf(buf, "%pM\n", bond->params.ad_actor_sys_macaddr);
>>>>+
>>>>+      return 0;
>>>>+}
>>>>+static DEVICE_ATTR(ad_actor_system_mac_address, S_IRUGO | S_IWUSR,
>>>>+                 bonding_show_ad_actor_sys_macaddr,
>>>>+                 bonding_sysfs_store_option);
>>>>+
>>>> static struct attribute *per_bond_attrs[] = {
>>>>       &dev_attr_slaves.attr,
>>>>       &dev_attr_mode.attr,
>>>>@@ -740,6 +755,7 @@ static struct attribute *per_bond_attrs[] = {
>>>>       &dev_attr_packets_per_slave.attr,
>>>>       &dev_attr_tlb_dynamic_lb.attr,
>>>>       &dev_attr_ad_actor_system_priority.attr,
>>>>+      &dev_attr_ad_actor_system_mac_address.attr,
>>>>       NULL,
>>>> };
>>>>
>>>>diff --git a/include/net/bond_options.h b/include/net/bond_options.h
>>>>index c2af1db37354..993ef73cd050 100644
>>>>--- a/include/net/bond_options.h
>>>>+++ b/include/net/bond_options.h
>>>>@@ -64,6 +64,7 @@ enum {
>>>>       BOND_OPT_SLAVES,
>>>>       BOND_OPT_TLB_DYNAMIC_LB,
>>>>       BOND_OPT_AD_ACTOR_SYSPRIO,
>>>>+      BOND_OPT_AD_ACTOR_SYS_MACADDR,
>>>>       BOND_OPT_LAST
>>>> };
>>>>
>>>>diff --git a/include/net/bonding.h b/include/net/bonding.h
>>>>index 7a5c79fcf866..cd2092e6bc71 100644
>>>>--- a/include/net/bonding.h
>>>>+++ b/include/net/bonding.h
>>>>@@ -144,6 +144,7 @@ struct bond_params {
>>>>       int tlb_dynamic_lb;
>>>>       struct reciprocal_value reciprocal_packets_per_slave;
>>>>       u16 ad_actor_sysprio;
>>>>+      u8 ad_actor_sys_macaddr[ETH_ALEN];
>>>> };
>>>>
>>>> struct bond_parm_tbl {
>>>>--
>>>>2.2.0.rc0.207.ga3a616c
>>>>
>
> ---
>         -Jay Vosburgh, jay.vosburgh@canonical.com

^ permalink raw reply

* Re: [PATCH net-next] net: rfs: add hash collision detection
From: Eric Dumazet @ 2015-02-07  2:24 UTC (permalink / raw)
  To: Tom Herbert; +Cc: David Miller, netdev, Ying Cai, Willem de Bruijn
In-Reply-To: <CA+mtBx-N1bQW8vscQf1-h=C0cmtTc2gG3ka+ixs1AMt7cP-Z_Q@mail.gmail.com>

On Fri, 2015-02-06 at 14:21 -0800, Tom Herbert wrote:

> Acked-by: Tom Herbert <therbert@google.com>
> 
> Eric, looks awesome! Can you share any performance numbers?

Right, numbers are awesome.

I flood one target with ~2.3 Mpps UDP packets coming from random IP
addresses.

UDP server uses SO_REUSEPORT with 8 sockets (I have 8 rx queues on the
host)


I force a small RFS table to show that hash collisions no longer
matter :

echo 512 >/proc/sys/net/core/rps_sock_flow_entries


softnettop tool (displaying /proc/net/softnet_stat in realtime)
shows that before starting the TCP flows, only 8 cpus are receiving and
process NIC irqs.

cpu:    recv     drop     time      rps 
26:   586720        0        0        0 
29:   586982        0        0        0 
32:   588582        0        0        0 
35:   589266        0        0        0 
38:   587796        0        0        0 
41:   588146        0        0        0 
44:   588158        0        0        0 
47:   587548        0        0        0 
 *:  4703282        0        0        5 


Then I start 200 netperf -t TCP_RR 

When the 200 TCP_RR flows start, we can see load nicely shifting,
but the UDP packets still not use RFS. TCP fl

cpu:    recv     drop     time      rps 
 0:     4254        0        0     1427 
 1:     4472        0        0     1460 
 2:     3070        0        0     1132 
 3:     4210        0        0     1417 
 4:     4472        0        0     1488 
 5:     2146        0        0      869 
 6:     4163        0        0     1456 
 7:     4354        0        0     1468 
 8:     3254        0        0     1170 
 9:     4468        0        0     1479 
10:     4449        0        0     1521 
11:     2788        0        0     1070 
12:     5902        0        0     1665 
13:     6160        0        0     1692 
14:     2319        0        0      945 
15:     5850        0        0     1686 
16:     5716        0        0     1643 
17:     3388        0        0     1224 
18:     5936        0        0     1724 
19:     6040        0        0     1691 
20:     2962        0        0     1076 
21:     5784        0        0     1696 
22:     6094        0        0     1717 
23:     2748        0        0      999 
24:     1392        0        0      638 
25:     1158        0        0      524 
26:   577970        0        0       77 
27:     1410        0        0      644 
28:     1166        0        0      544 
29:   575270        0        0        5 
30:     1158        0        0      523 
31:      972        0        0      444 
32:   574306        0        0      181 
33:     1248        0        0      575 
34:     1094        0        0      502 
35:   577116        0        0       69 
36:     2142        0        0      893 
37:     1384        0        0      587 
38:   577470        0        0        7 
39:     2029        0        0      856 
40:     1858        0        0      780 
41:   574744        0        0       46 
42:     1946        0        0      806 
43:     1711        0        0      719 
44:   570190        0        0       81 
45:     2210        0        0      872 
46:     1670        0        0      702 
47:   572758        0        0       68 
 *:  4729371        0        0    44858 

cpu:    recv     drop     time      rps 
 0:    48770        0        0    13778 
 1:    49198        0        0    13979 
 2:    24580        0        0     8631 
 3:    48272        0        0    13642 
 4:    48578        0        0    13831 
 5:    23716        0        0     8631 
 6:    48034        0        0    13648 
 7:    49408        0        0    13848 
 8:    26147        0        0     9068 
 9:    48678        0        0    13843 
10:    49515        0        0    13931 
11:    29836        0        0    10079 
12:    45828        0        0    13331 
13:    46654        0        0    13553 
14:    19850        0        0     7452 
15:    44382        0        0    13083 
16:    44667        0        0    13072 
17:    27196        0        0     9429 
18:    44574        0        0    13069 
19:    45076        0        0    13193 
20:    27352        0        0     9329 
21:    45468        0        0    13183 
22:    46264        0        0    13435 
23:    23598        0        0     8485 
24:    14248        0        0     6061 
25:    13624        0        0     5851 
26:   508738        0        0      828 
27:    14516        0        0     6214 
28:    13354        0        0     5700 
29:   512006        0        0      604 
30:    14686        0        0     6249 
31:    13866        0        0     5944 
32:   491190        0        0     1101 
33:    14628        0        0     6237 
34:    14164        0        0     6025 
35:   499178        0        0     1513 
36:    13138        0        0     5687 
37:    11964        0        0     5220 
38:   523120        0        0      413 
39:    13565        0        0     5808 
40:    12742        0        0     5500 
41:   485162        0        0     1343 
42:    13254        0        0     5686 
43:    12096        0        0     5254 
44:   464680        0        0     1615 
45:    13450        0        0     5781 
46:    12400        0        0     5346 
47:   493070        0        0      935 
 *:  5148480        0        0   388438 

cpu:    recv     drop     time      rps 
 0:    46596        0        0    13977 
 1:    48633        0        0    14331 
 2:    24006        0        0     8909 
 3:    47844        0        0    14080 
 4:    47742        0        0    14067 
 5:    26642        0        0     9605 
 6:    47796        0        0    14117 
 7:    48806        0        0    14432 
 8:    27936        0        0     9934 
 9:    48034        0        0    14233 
10:    48892        0        0    14377 
11:    30650        0        0    10512 
12:    45651        0        0    13614 
13:    45439        0        0    13536 
14:    24337        0        0     8877 
15:    45379        0        0    13666 
16:    45695        0        0    13643 
17:    26552        0        0     9452 
18:    45513        0        0    13608 
19:    46588        0        0    13930 
20:    26242        0        0     9273 
21:    45521        0        0    13670 
22:    46255        0        0    13729 
23:    28166        0        0     9842 
24:    13998        0        0     6086 
25:    12518        0        0     5512 
26:   503796        0        0      621 
27:    13732        0        0     6002 
28:    12802        0        0     5611 
29:   507766        0        0      689 
30:    13968        0        0     6044 
31:    13012        0        0     5648 
32:   488760        0        0      938 
33:    13969        0        0     6044 
34:    12666        0        0     5545 
35:   497482        0        0     1497 
36:    13074        0        0     5715 
37:    12187        0        0     5338 
38:   520414        0        0      496 
39:    13752        0        0     5988 
40:    12046        0        0     5297 
41:   480412        0        0      904 
42:    13436        0        0     5845 
43:    11978        0        0     5286 
44:   461146        0        0     1288 
45:    12982        0        0     5655 
46:    12872        0        0     5643 
47:   488788        0        0     1066 
 *:  5122471        0        0   398172 

cpu:    recv     drop     time      rps 
 0:    46970        0        0    13467 
 1:    48129        0        0    13914 
 2:    25876        0        0     9206 
 3:    47672        0        0    13723 
 4:    48566        0        0    13875 
 5:    25575        0        0     9009 
 6:    47342        0        0    13673 
 7:    48636        0        0    13889 
 8:    28038        0        0     9722 
 9:    48298        0        0    13875 
10:    48662        0        0    13911 
11:    28412        0        0     9777 
12:    45025        0        0    13323 
13:    45620        0        0    13422 
14:    20808        0        0     7800 
15:    44481        0        0    13271 
16:    45032        0        0    13324 
17:    25698        0        0     9155 
18:    45125        0        0    13483 
19:    46371        0        0    13627 
20:    27234        0        0     9437 
21:    44899        0        0    13234 
22:    46065        0        0    13530 
23:    24118        0        0     8629 
24:    14416        0        0     6137 
25:    13690        0        0     5863 
26:   508418        0        0      905 
27:    14780        0        0     6295 
28:    13288        0        0     5716 
29:   509010        0        0     1136 
30:    15080        0        0     6443 
31:    13378        0        0     5771 
32:   489950        0        0     1302 
33:    14410        0        0     6157 
34:    13712        0        0     5894 
35:   496760        0        0     1153 
36:    13906        0        0     5978 
37:    12198        0        0     5326 
38:   520846        0        0      444 
39:    13206        0        0     5709 
40:    13020        0        0     5636 
41:   482136        0        0     1029 
42:    13068        0        0     5616 
43:    12982        0        0     5636 
44:   462626        0        0     1378 
45:    13342        0        0     5765 
46:    12784        0        0     5608 
47:   491690        0        0      717 
 *:  5131348        0        0   391890 

cpu:    recv     drop     time      rps 
 0:    45472        0        0    13241 
 1:    46628        0        0    13471 
 2:    25556        0        0     8988 
 3:    46082        0        0    13369 
 4:    45573        0        0    13263 
 5:    28061        0        0     9506 
 6:    45806        0        0    13329 
 7:    46890        0        0    13631 
 8:    28321        0        0     9711 
 9:    45826        0        0    13339 
10:    46522        0        0    13569 
11:    27168        0        0     9467 
12:    47750        0        0    13717 
13:    47630        0        0    13619 
14:    20660        0        0     7846 
15:    47224        0        0    13707 
16:    48439        0        0    13884 
17:    23894        0        0     8646 
18:    47019        0        0    13666 
19:    47532        0        0    13811 
20:    26957        0        0     9465 
21:    47380        0        0    13703 
22:    48520        0        0    14014 
23:    24379        0        0     8775 
24:    13100        0        0     5633 
25:    13210        0        0     5696 
26:   506252        0        0      887 
27:    13564        0        0     5865 
28:    12258        0        0     5294 
29:   510674        0        0     1436 
30:    12892        0        0     5551 
31:    13112        0        0     5668 
32:   492734        0        0     1633 
33:    13480        0        0     5775 
34:    12400        0        0     5367 
35:   497366        0        0     1371 
36:    14236        0        0     6109 
37:    12728        0        0     5552 
38:   519158        0        0      365 
39:    14322        0        0     6096 
40:    13432        0        0     5801 
41:   481236        0        0      832 
42:    14584        0        0     6242 
43:    14200        0        0     6099 
44:   463266        0        0     1242 
45:    14130        0        0     6056 
46:    13574        0        0     5824 
47:   490142        0        0      778 
 *:  5131339        0        0   390909 

cpu:    recv     drop     time      rps 
 0:    46704        0        0    13515 
 1:    46175        0        0    13421 
 2:    22761        0        0     8388 
 3:    47142        0        0    13758 
 4:    46908        0        0    13532 
 5:    27770        0        0     9681 
 6:    47210        0        0    13638 
 7:    47645        0        0    13657 
 8:    28668        0        0     9829 
 9:    47806        0        0    13763 
10:    47638        0        0    13621 
11:    30896        0        0    10260 
12:    47778        0        0    13721 
13:    48396        0        0    13753 
14:    18130        0        0     7339 
15:    46427        0        0    13522 
16:    47578        0        0    13659 
17:    25465        0        0     8996 
18:    47052        0        0    13537 
19:    48184        0        0    13839 
20:    27105        0        0     9526 
21:    48230        0        0    13697 
22:    49176        0        0    13919 
23:    20728        0        0     7863 
24:    13626        0        0     5844 
25:    11770        0        0     5112 
26:   532288        0        0      549 
27:    13960        0        0     6030 
28:    13534        0        0     5863 
29:   537130        0        0     1374 
30:    14702        0        0     6259 
31:    13776        0        0     5923 
32:   520046        0        0     1242 
33:    14292        0        0     6095 
34:    13684        0        0     5868 
35:   524026        0        0     1466 
36:    14931        0        0     6375 
37:    10918        0        0     4738 
38:   545740        0        0      119 
39:    15372        0        0     6580 
40:    13984        0        0     5992 
41:   507908        0        0     1185 
42:    15540        0        0     6595 
43:    14538        0        0     6243 
44:   486684        0        0     1202 
45:    15100        0        0     6417 
46:    13423        0        0     5781 
47:   515604        0        0      333 
 *:  5354148        0        0   393619 

cpu:    recv     drop     time      rps 
 0:    49981        0        0    14007 
 1:    51769        0        0    14362 
 2:    21066        0        0     7982 
 3:    51477        0        0    14326 
 4:    50566        0        0    14090 
 5:    21334        0        0     8299 
 6:    50853        0        0    14238 
 7:    52091        0        0    14379 
 8:    22447        0        0     8502 
 9:    51318        0        0    14373 
10:    52682        0        0    14605 
11:    31434        0        0    10542 
12:    45672        0        0    13385 
13:    46592        0        0    13574 
14:    19514        0        0     7595 
15:    45765        0        0    13409 
16:    45518        0        0    13260 
17:    22627        0        0     8526 
18:    45697        0        0    13382 
19:    46958        0        0    13667 
20:    25211        0        0     9039 
21:    46581        0        0    13685 
22:    46623        0        0    13493 
23:    22625        0        0     8326 
24:    15724        0        0     6612 
25:    13978        0        0     5959 
26:   555430        0        0      296 
27:    16266        0        0     6831 
28:    14319        0        0     6139 
29:   557434        0        0      232 
30:    17372        0        0     7232 
31:    14600        0        0     6244 
32:   541476        0        0      601 
33:    17265        0        0     7225 
34:    15755        0        0     6693 
35:   550066        0        0     1764 
36:    14554        0        0     6240 
37:    12873        0        0     5575 
38:   569992        0        0      323 
39:    14685        0        0     6306 
40:    13202        0        0     5755 
41:   531414        0        0      571 
42:    15002        0        0     6467 
43:    13336        0        0     5746 
44:   512364        0        0     1019 
45:    14469        0        0     6158 
46:    13390        0        0     5813 
47:   541256        0        0      644 
 *:  5562623        0        0   397491 

cpu:    recv     drop     time      rps 
 0:    49230        0        0    13561 
 1:    48356        0        0    13262 
 2:    25240        0        0     8872 
 3:    48772        0        0    13475 
 4:    49256        0        0    13579 
 5:    26330        0        0     9117 
 6:    49474        0        0    13638 
 7:    50230        0        0    13808 
 8:    27763        0        0     9450 
 9:    49538        0        0    13641 
10:    50428        0        0    13888 
11:    26006        0        0     9110 
12:    46391        0        0    13273 
13:    46546        0        0    13354 
14:    18240        0        0     7144 
15:    45833        0        0    13084 
16:    46194        0        0    13148 
17:    26255        0        0     9218 
18:    46387        0        0    13280 
19:    47606        0        0    13546 
20:    22683        0        0     8411 
21:    47091        0        0    13458 
22:    47880        0        0    13577 
23:    22779        0        0     8252 
24:    15551        0        0     6458 
25:    14146        0        0     5986 
26:   558688        0        0      779 
27:    15856        0        0     6559 
28:    13980        0        0     5886 
29:   562008        0        0     1002 
30:    16178        0        0     6766 
31:    14736        0        0     6213 
32:   542428        0        0     1121 
33:    15828        0        0     6541 
34:    14944        0        0     6336 
35:   547546        0        0      829 
36:    13882        0        0     5942 
37:    11804        0        0     5165 
38:   571056        0        0      227 
39:    15422        0        0     6529 
40:    12786        0        0     5514 
41:   532399        0        0     1073 
42:    14810        0        0     6316 
43:    13254        0        0     5721 
44:   509890        0        0      649 
45:    14717        0        0     6280 
46:    12160        0        0     5294 
47:   538686        0        0      547 
 *:  5557263        0        0   388879 

cpu:    recv     drop     time      rps 
 0:    48494        0        0    13610 
 1:    48450        0        0    13667 
 2:    18908        0        0     7389 
 3:    47301        0        0    13496 
 4:    48212        0        0    13626 
 5:    24524        0        0     8817 
 6:    48055        0        0    13477 
 7:    50226        0        0    13908 
 8:    26093        0        0     9198 
 9:    49130        0        0    13734 
10:    50252        0        0    14079 
11:    30880        0        0    10275 
12:    46759        0        0    13098 
13:    48464        0        0    13494 
14:    21192        0        0     7887 
15:    47295        0        0    13352 
16:    48224        0        0    13641 
17:    27363        0        0     9500 
18:    46990        0        0    13353 
19:    48559        0        0    13695 
20:    24237        0        0     8670 
21:    48024        0        0    13583 
22:    49013        0        0    13651 
23:    22739        0        0     8365 
24:    14664        0        0     6240 
25:    10190        0        0     4505 
26:   556422        0        0      301 
27:    14702        0        0     6260 
28:    13725        0        0     5924 
29:   560214        0        0      826 
30:    15144        0        0     6412 
31:    14250        0        0     6075 
32:   540102        0        0      972 
33:    15122        0        0     6408 
34:    14358        0        0     6157 
35:   549364        0        0     1676 
36:    14894        0        0     6302 
37:    13023        0        0     5569 
38:   571308        0        0      496 
39:    15154        0        0     6391 
40:    14430        0        0     6116 
41:   530950        0        0      945 
42:    15478        0        0     6571 
43:    13633        0        0     5849 
44:   511994        0        0     1052 
45:    14892        0        0     6327 
46:    13216        0        0     5686 
47:   541362        0        0      559 
 *:  5557975        0        0   391184 

cpu:    recv     drop     time      rps 
 0:    49414        0        0    13841 
 1:    50425        0        0    14087 
 2:    19888        0        0     7699 
 3:    49729        0        0    14059 
 4:    49847        0        0    13937 
 5:    20906        0        0     7860 
 6:    49566        0        0    13901 
 7:    49948        0        0    13943 
 8:    26602        0        0     9373 
 9:    50721        0        0    14104 
10:    50977        0        0    14123 
11:    31706        0        0    10511 
12:    47948        0        0    13746 
13:    48042        0        0    13843 
14:    17106        0        0     7039 
15:    47788        0        0    13749 
16:    47675        0        0    13651 
17:    22882        0        0     8337 
18:    47063        0        0    13544 
19:    48308        0        0    13791 
20:    23578        0        0     8637 
21:    48128        0        0    13847 
22:    48846        0        0    13843 
23:    20482        0        0     7744 
24:    15436        0        0     6517 
25:    12962        0        0     5592 
26:   555592        0        0      216 
27:    16100        0        0     6811 
28:    13358        0        0     5712 
29:   558520        0        0      572 
30:    15792        0        0     6618 
31:    14698        0        0     6277 
32:   540146        0        0     1166 
33:    15970        0        0     6711 
34:    15034        0        0     6345 
35:   548184        0        0     2099 
36:    15194        0        0     6493 
37:    12204        0        0     5338 
38:   570088        0        0       77 
39:    15828        0        0     6732 
40:    13156        0        0     5694 
41:   528860        0        0      906 
42:    15874        0        0     6783 
43:    13476        0        0     5795 
44:   510034        0        0      973 
45:    15476        0        0     6624 
46:    13382        0        0     5816 
47:   538046        0        0      551 
 *:  5550985        0        0   395627 

cpu:    recv     drop     time      rps 
 0:    42896        0        0    12157 
 1:    43502        0        0    12338 
 2:    24072        0        0     8449 
 3:    42853        0        0    12258 
 4:    43146        0        0    12331 
 5:    21194        0        0     7741 
 6:    42003        0        0    12066 
 7:    43034        0        0    12182 
 8:    22830        0        0     7946 
 9:    43633        0        0    12347 
10:    43731        0        0    12329 
11:    24231        0        0     8449 
12:    43542        0        0    12251 
13:    44341        0        0    12409 
14:    19231        0        0     7209 
15:    43392        0        0    12284 
16:    43544        0        0    12189 
17:    24620        0        0     8463 
18:    42781        0        0    12012 
19:    44263        0        0    12439 
20:    22462        0        0     8016 
21:    43984        0        0    12512 
22:    44554        0        0    12435 
23:    19194        0        0     7287 
24:    13028        0        0     5565 
25:    11452        0        0     4959 
26:   558724        0        0      850 
27:    13408        0        0     5708 
28:    11022        0        0     4745 
29:   559438        0        0      645 
30:    13428        0        0     5695 
31:    12946        0        0     5524 
32:   543112        0        0     1045 
33:    13006        0        0     5520 
34:    12110        0        0     5191 
35:   547556        0        0      838 
36:    13546        0        0     5723 
37:    12582        0        0     5456 
38:   571372        0        0      424 
39:    14040        0        0     5898 
40:    12936        0        0     5525 
41:   536642        0        0      978 
42:    14164        0        0     5957 
43:    13158        0        0     5671 
44:   518283        0        0      975 
45:    13834        0        0     5860 
46:    11914        0        0     5093 
47:   542846        0        0      489 
 *:  5457580        0        0   354433 

TCP_RR workload ends....

cpu:    recv     drop     time      rps 
26:   588684        0        0        0 
29:   589572        0        0        0 
32:   589626        0        0        0 
35:   588128        0        0        0 
38:   589176        0        0        0 
41:   589258        0        0        0 
44:   589546        0        0        0 
47:   587540        0        0        0 
 *:  4711633        0        0       12 

Thanks

^ permalink raw reply

* [PATCH] vxlan: Wrong type passed to %pIS
From: Rasmus Villemoes @ 2015-02-07  2:17 UTC (permalink / raw)
  To: David S. Miller, Pravin B Shelar, Nicolas Dichtel
  Cc: Rasmus Villemoes, netdev, linux-kernel

src_ip is a pointer to a union vxlan_addr, one member of which is a
struct sockaddr. Passing a pointer to src_ip is wrong; one should pass
the value of src_ip itself. Since %pIS formally expects something of
type struct sockaddr*, let's pass a pointer to the appropriate union
member, though this of course doesn't change the generated code.

Fixes: e4c7ed415387 ("vxlan: add ipv6 support")
Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
---
 drivers/net/vxlan.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index a8c755dcab14..11defbb24183 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -991,7 +991,7 @@ static bool vxlan_snoop(struct net_device *dev,
 		if (net_ratelimit())
 			netdev_info(dev,
 				    "%pM migrated from %pIS to %pIS\n",
-				    src_mac, &rdst->remote_ip, &src_ip);
+				    src_mac, &rdst->remote_ip.sa, &src_ip->sa);
 
 		rdst->remote_ip = *src_ip;
 		f->updated = jiffies;
-- 
2.1.3

^ permalink raw reply related

* Re: [PATCH next 5/6] bonding: Allow userspace to set macaddr on bonding-dev
From: Jay Vosburgh @ 2015-02-07  1:54 UTC (permalink / raw)
  To: Mahesh Bandewar
  Cc: Andy Gospodarek, Veaceslav Falico, Nikolay Aleksandrov,
	David Miller, netdev, Eric Dumazet, Maciej Żenczykowski
In-Reply-To: <CAF2d9jgV5adAjydN18Ct7BVJJcc=FRc+5icNMS=pRQMRX=83+w@mail.gmail.com>

Mahesh Bandewar <maheshb@google.com> wrote:

>On Fri, Feb 6, 2015 at 5:20 PM, Jay Vosburgh <jay.vosburgh@canonical.com> wrote:
>> Mahesh Bandewar <maheshb@google.com> wrote:
>>
>>>This patch allows user-space to set the mac-address on the bonding device.
>>>This mac-address can not be NULL or a Multicast. If the mac-address is set
>>>from user-space; kernel will honor it and will not overwrite it. In the
>>>absense (value from user space); the logic will default to using the
>>>masters' mac as the mac address for the bonding device.
>>>
>>>It can be set using example code below -
>>>
>>>   # modprobe bonding mode=4
>>>   # sys_mac_addr=$(printf '%02x:%02x:%02x:%02x:%02x:%02x' \
>>>                    $(( (RANDOM & 0xFE) | 0x02 )) \
>>>                    $(( RANDOM & 0xFF )) \
>>>                    $(( RANDOM & 0xFF )) \
>>>                    $(( RANDOM & 0xFF )) \
>>>                    $(( RANDOM & 0xFF )) \
>>>                    $(( RANDOM & 0xFF )))
>>>   # echo $sys_mac_addr > /sys/class/net/bond0/bonding/ad_actor_system_mac_address
>>>   # echo +eth1 > /sys/class/net/bond0/bonding/slaves
>>>   ...
>>>   # ip link set bond0 up
>>
>>         How is this patch functionally different from setting the
>> bonding master's MAC address to a particular value prior to adding any
>> slaves?
>>
>
>Maciej is correct but I think I was bit ambiguous about it in the
>commit message which might have made you think this way. I'll reword
>the commit message.

	Thanks; presumably there is some administrative reason for this.

	Also, for patches 4, 5 and 6, I believe current practice is to
provide a netlink / iproute2 facility for options.

	-J


>>         -J
>>
>>>Signed-off-by: Mahesh Bandewar <maheshb@google.com>
>>>---
>>> drivers/net/bonding/bond_3ad.c     |  7 ++++++-
>>> drivers/net/bonding/bond_main.c    |  1 +
>>> drivers/net/bonding/bond_options.c | 29 +++++++++++++++++++++++++++++
>>> drivers/net/bonding/bond_procfs.c  |  6 ++++++
>>> drivers/net/bonding/bond_sysfs.c   | 16 ++++++++++++++++
>>> include/net/bond_options.h         |  1 +
>>> include/net/bonding.h              |  1 +
>>> 7 files changed, 60 insertions(+), 1 deletion(-)
>>>
>>>diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
>>>index 1177f96194dd..373d3db3809f 100644
>>>--- a/drivers/net/bonding/bond_3ad.c
>>>+++ b/drivers/net/bonding/bond_3ad.c
>>>@@ -1914,7 +1914,12 @@ void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution)
>>>
>>>               BOND_AD_INFO(bond).system.sys_priority =
>>>                       bond->params.ad_actor_sysprio;
>>>-              BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->dev->dev_addr);
>>>+              if (is_zero_ether_addr(bond->params.ad_actor_sys_macaddr))
>>>+                      BOND_AD_INFO(bond).system.sys_mac_addr =
>>>+                          *((struct mac_addr *)bond->dev->dev_addr);
>>>+              else
>>>+                      BOND_AD_INFO(bond).system.sys_mac_addr =
>>>+                          *((struct mac_addr *)bond->params.ad_actor_sys_macaddr);
>>>
>>>               /* initialize how many times this module is called in one
>>>                * second (should be about every 100ms)
>>>diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
>>>index 561b2bde5aeb..1a6735ef2ea7 100644
>>>--- a/drivers/net/bonding/bond_main.c
>>>+++ b/drivers/net/bonding/bond_main.c
>>>@@ -4440,6 +4440,7 @@ static int bond_check_params(struct bond_params *params)
>>>       params->packets_per_slave = packets_per_slave;
>>>       params->tlb_dynamic_lb = 1; /* Default value */
>>>       params->ad_actor_sysprio = ad_actor_sysprio;
>>>+      eth_zero_addr(params->ad_actor_sys_macaddr);
>>>       if (packets_per_slave > 0) {
>>>               params->reciprocal_packets_per_slave =
>>>                       reciprocal_value(packets_per_slave);
>>>diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
>>>index d8f6760143ae..330d48b6a1e6 100644
>>>--- a/drivers/net/bonding/bond_options.c
>>>+++ b/drivers/net/bonding/bond_options.c
>>>@@ -72,6 +72,8 @@ static int bond_option_tlb_dynamic_lb_set(struct bonding *bond,
>>>                                 const struct bond_opt_value *newval);
>>> static int bond_option_ad_actor_sysprio_set(struct bonding *bond,
>>>                                 const struct bond_opt_value *newval);
>>>+static int bond_option_ad_actor_sys_macaddr_set(struct bonding *bond,
>>>+                                const struct bond_opt_value *newval);
>>>
>>>
>>> static const struct bond_opt_value bond_mode_tbl[] = {
>>>@@ -396,6 +398,13 @@ static const struct bond_option bond_opts[BOND_OPT_LAST] = {
>>>               .values = bond_ad_actor_sysprio_tbl,
>>>               .set = bond_option_ad_actor_sysprio_set,
>>>       },
>>>+      [BOND_OPT_AD_ACTOR_SYS_MACADDR] = {
>>>+              .id = BOND_OPT_AD_ACTOR_SYS_MACADDR,
>>>+              .name = "ad_actor_system_mac_address",
>>>+              .unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_8023AD)),
>>>+              .flags = BOND_OPTFLAG_RAWVAL | BOND_OPTFLAG_IFDOWN,
>>>+              .set = bond_option_ad_actor_sys_macaddr_set,
>>>+      },
>>> };
>>>
>>> /* Searches for an option by name */
>>>@@ -1376,3 +1385,23 @@ static int bond_option_ad_actor_sysprio_set(struct bonding *bond,
>>>       bond->params.ad_actor_sysprio = newval->value;
>>>       return 0;
>>> }
>>>+
>>>+static int bond_option_ad_actor_sys_macaddr_set(struct bonding *bond,
>>>+                                          const struct bond_opt_value *newval)
>>>+{
>>>+      u8 macaddr[ETH_ALEN];
>>>+      int i;
>>>+
>>>+      i = sscanf(newval->string, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
>>>+                 &macaddr[0], &macaddr[1], &macaddr[2],
>>>+                 &macaddr[3], &macaddr[4], &macaddr[5]);
>>>+
>>>+      if (i != ETH_ALEN || !is_valid_ether_addr(macaddr)) {
>>>+              netdev_err(bond->dev, "Invalid MAC address.\n");
>>>+              return -EINVAL;
>>>+      }
>>>+
>>>+      ether_addr_copy(bond->params.ad_actor_sys_macaddr, macaddr);
>>>+
>>>+      return 0;
>>>+}
>>>diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c
>>>index 9e33c48886ef..81452ced852f 100644
>>>--- a/drivers/net/bonding/bond_procfs.c
>>>+++ b/drivers/net/bonding/bond_procfs.c
>>>@@ -136,6 +136,8 @@ static void bond_info_show_master(struct seq_file *seq)
>>>                          optval->string);
>>>               seq_printf(seq, "System priority: %d\n",
>>>                               BOND_AD_INFO(bond).system.sys_priority);
>>>+              seq_printf(seq, "System MAC address: %pM\n",
>>>+                              &BOND_AD_INFO(bond).system.sys_mac_addr);
>>>
>>>               if (__bond_3ad_get_active_agg_info(bond, &ad_info)) {
>>>                       seq_printf(seq, "bond %s has no active aggregator\n",
>>>@@ -198,6 +200,8 @@ static void bond_info_show_slave(struct seq_file *seq,
>>>                       seq_puts(seq, "details actor lacp pdu:\n");
>>>                       seq_printf(seq, "    system priority: %d\n",
>>>                                  port->actor_system_priority);
>>>+                      seq_printf(seq, "    system mac address: %pM\n",
>>>+                                 &port->actor_system);
>>>                       seq_printf(seq, "    port key: %d\n",
>>>                                  port->actor_oper_port_key);
>>>                       seq_printf(seq, "    port priority: %d\n",
>>>@@ -210,6 +214,8 @@ static void bond_info_show_slave(struct seq_file *seq,
>>>                       seq_puts(seq, "details partner lacp pdu:\n");
>>>                       seq_printf(seq, "    system priority: %d\n",
>>>                                  port->partner_oper.system_priority);
>>>+                      seq_printf(seq, "    system mac address: %pM\n",
>>>+                                 &port->partner_oper.system);
>>>                       seq_printf(seq, "    oper key: %d\n",
>>>                                  port->partner_oper.key);
>>>                       seq_printf(seq, "    port priority: %d\n",
>>>diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
>>>index 4350aa06f867..91713d0b6685 100644
>>>--- a/drivers/net/bonding/bond_sysfs.c
>>>+++ b/drivers/net/bonding/bond_sysfs.c
>>>@@ -706,6 +706,21 @@ static ssize_t bonding_show_ad_actor_sysprio(struct device *d,
>>> static DEVICE_ATTR(ad_actor_system_priority, S_IRUGO | S_IWUSR,
>>>                  bonding_show_ad_actor_sysprio, bonding_sysfs_store_option);
>>>
>>>+static ssize_t bonding_show_ad_actor_sys_macaddr(struct device *d,
>>>+                                               struct device_attribute *attr,
>>>+                                               char *buf)
>>>+{
>>>+      struct bonding *bond = to_bond(d);
>>>+
>>>+      if (BOND_MODE(bond) == BOND_MODE_8023AD)
>>>+              return sprintf(buf, "%pM\n", bond->params.ad_actor_sys_macaddr);
>>>+
>>>+      return 0;
>>>+}
>>>+static DEVICE_ATTR(ad_actor_system_mac_address, S_IRUGO | S_IWUSR,
>>>+                 bonding_show_ad_actor_sys_macaddr,
>>>+                 bonding_sysfs_store_option);
>>>+
>>> static struct attribute *per_bond_attrs[] = {
>>>       &dev_attr_slaves.attr,
>>>       &dev_attr_mode.attr,
>>>@@ -740,6 +755,7 @@ static struct attribute *per_bond_attrs[] = {
>>>       &dev_attr_packets_per_slave.attr,
>>>       &dev_attr_tlb_dynamic_lb.attr,
>>>       &dev_attr_ad_actor_system_priority.attr,
>>>+      &dev_attr_ad_actor_system_mac_address.attr,
>>>       NULL,
>>> };
>>>
>>>diff --git a/include/net/bond_options.h b/include/net/bond_options.h
>>>index c2af1db37354..993ef73cd050 100644
>>>--- a/include/net/bond_options.h
>>>+++ b/include/net/bond_options.h
>>>@@ -64,6 +64,7 @@ enum {
>>>       BOND_OPT_SLAVES,
>>>       BOND_OPT_TLB_DYNAMIC_LB,
>>>       BOND_OPT_AD_ACTOR_SYSPRIO,
>>>+      BOND_OPT_AD_ACTOR_SYS_MACADDR,
>>>       BOND_OPT_LAST
>>> };
>>>
>>>diff --git a/include/net/bonding.h b/include/net/bonding.h
>>>index 7a5c79fcf866..cd2092e6bc71 100644
>>>--- a/include/net/bonding.h
>>>+++ b/include/net/bonding.h
>>>@@ -144,6 +144,7 @@ struct bond_params {
>>>       int tlb_dynamic_lb;
>>>       struct reciprocal_value reciprocal_packets_per_slave;
>>>       u16 ad_actor_sysprio;
>>>+      u8 ad_actor_sys_macaddr[ETH_ALEN];
>>> };
>>>
>>> struct bond_parm_tbl {
>>>--
>>>2.2.0.rc0.207.ga3a616c
>>>

---
	-Jay Vosburgh, jay.vosburgh@canonical.com

^ permalink raw reply

* Re: [PATCH] af_packet: don't pass empty blocks for PACKET_V3
From: Willem de Bruijn @ 2015-02-07  1:45 UTC (permalink / raw)
  To: Alexander Drozdov
  Cc: David S. Miller, Daniel Borkmann, Eric Dumazet, Al Viro,
	Michael S. Tsirkin, Network Development, linux-kernel, Guy Harris,
	Dan Collins
In-Reply-To: <54D4651D.6060300@gmail.com>

On Thu, Feb 5, 2015 at 10:54 PM, Alexander Drozdov <al.drozdov@gmail.com> wrote:
> On 05.02.2015 23:01:38 +0300 Willem de Bruijn wrote:
>>
>> On Wed, Feb 4, 2015 at 9:58 PM, Alexander Drozdov <al.drozdov@gmail.com>
>> wrote:
>>>
>>> Don't close an empty block on timeout. Its meaningless to
>>> pass it to the user. Moreover, passing empty blocks wastes
>>> CPU & buffer space increasing probability of packets
>>> dropping on small timeouts.
>>>
>>> Side effect of this patch is indefinite user-space wait
>>> in poll on idle links. But, I believe its better to set
>>> timeout for poll(2) when needed than to get empty blocks
>>> every millisecond when not needed.
>>
>> This change would break existing applications that have come
>> to depend on the periodic signal.
>>
>> I don't disagree with the argument that the data ready signal
>> should be sent only when a block is full or a timer expires and
>> at least some data is waiting, but that is moot at this point.
>
> I missed something. As pointed by Guy Harris <guy@alum.mit.edu>,
> before the previous patch periodic signal was not delivered. The previous
> patch
> (da413eec729dae5dc by Dan Collins <dan@dcollins.co.nz>) is for 3.19 kernel
> only. Should we care about existing 3.19-only applications?

It does sound reasonable to expect processes to handle infinite sleep
on no data if that is the historical behavior of the interface.

>>
>>> Signed-off-by: Alexander Drozdov <al.drozdov@gmail.com>
>>> ---
>>>   net/packet/af_packet.c | 10 +++++++++-
>>>   1 file changed, 9 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
>>> index 9cfe2e1..9a2f70a 100644
>>> --- a/net/packet/af_packet.c
>>> +++ b/net/packet/af_packet.c
>>> @@ -698,6 +698,10 @@ static void prb_retire_rx_blk_timer_expired(unsigned
>>> long data)
>>>
>>>          if (pkc->last_kactive_blk_num == pkc->kactive_blk_num) {
>>>                  if (!frozen) {
>>> +                       if (!BLOCK_NUM_PKTS(pbd)) {
>>> +                               /* An empty block. Just refresh the
>>> timer. */
>>> +                               goto refresh_timer;
>>> +                       }
>>>                          prb_retire_current_block(pkc, po,
>>> TP_STATUS_BLK_TMO);
>>>                          if (!prb_dispatch_next_block(pkc, po))
>>>                                  goto refresh_timer;
>>> @@ -798,7 +802,11 @@ static void prb_close_block(struct tpacket_kbdq_core
>>> *pkc1,
>>>                  h1->ts_last_pkt.ts_sec = last_pkt->tp_sec;
>>>                  h1->ts_last_pkt.ts_nsec = last_pkt->tp_nsec;
>>>          } else {
>>> -               /* Ok, we tmo'd - so get the current time */
>>> +               /* Ok, we tmo'd - so get the current time.
>>> +                *
>>> +                * It shouldn't really happen as we don't close empty
>>> +                * blocks. See prb_retire_rx_blk_timer_expired().
>>> +                */
>>>                  struct timespec ts;
>>>                  getnstimeofday(&ts);
>>>                  h1->ts_last_pkt.ts_sec = ts.tv_sec;
>>> --
>>> 1.9.1
>>>
>

^ permalink raw reply

* Re: [PATCH next 5/6] bonding: Allow userspace to set macaddr on bonding-dev
From: Mahesh Bandewar @ 2015-02-07  1:35 UTC (permalink / raw)
  To: Jay Vosburgh
  Cc: Andy Gospodarek, Veaceslav Falico, Nikolay Aleksandrov,
	David Miller, netdev, Eric Dumazet, Maciej Żenczykowski
In-Reply-To: <4192.1423272023@famine>

On Fri, Feb 6, 2015 at 5:20 PM, Jay Vosburgh <jay.vosburgh@canonical.com> wrote:
> Mahesh Bandewar <maheshb@google.com> wrote:
>
>>This patch allows user-space to set the mac-address on the bonding device.
>>This mac-address can not be NULL or a Multicast. If the mac-address is set
>>from user-space; kernel will honor it and will not overwrite it. In the
>>absense (value from user space); the logic will default to using the
>>masters' mac as the mac address for the bonding device.
>>
>>It can be set using example code below -
>>
>>   # modprobe bonding mode=4
>>   # sys_mac_addr=$(printf '%02x:%02x:%02x:%02x:%02x:%02x' \
>>                    $(( (RANDOM & 0xFE) | 0x02 )) \
>>                    $(( RANDOM & 0xFF )) \
>>                    $(( RANDOM & 0xFF )) \
>>                    $(( RANDOM & 0xFF )) \
>>                    $(( RANDOM & 0xFF )) \
>>                    $(( RANDOM & 0xFF )))
>>   # echo $sys_mac_addr > /sys/class/net/bond0/bonding/ad_actor_system_mac_address
>>   # echo +eth1 > /sys/class/net/bond0/bonding/slaves
>>   ...
>>   # ip link set bond0 up
>
>         How is this patch functionally different from setting the
> bonding master's MAC address to a particular value prior to adding any
> slaves?
>

Maciej is correct but I think I was bit ambiguous about it in the
commit message which might have made you think this way. I'll reword
the commit message.

>         -J
>
>>Signed-off-by: Mahesh Bandewar <maheshb@google.com>
>>---
>> drivers/net/bonding/bond_3ad.c     |  7 ++++++-
>> drivers/net/bonding/bond_main.c    |  1 +
>> drivers/net/bonding/bond_options.c | 29 +++++++++++++++++++++++++++++
>> drivers/net/bonding/bond_procfs.c  |  6 ++++++
>> drivers/net/bonding/bond_sysfs.c   | 16 ++++++++++++++++
>> include/net/bond_options.h         |  1 +
>> include/net/bonding.h              |  1 +
>> 7 files changed, 60 insertions(+), 1 deletion(-)
>>
>>diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
>>index 1177f96194dd..373d3db3809f 100644
>>--- a/drivers/net/bonding/bond_3ad.c
>>+++ b/drivers/net/bonding/bond_3ad.c
>>@@ -1914,7 +1914,12 @@ void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution)
>>
>>               BOND_AD_INFO(bond).system.sys_priority =
>>                       bond->params.ad_actor_sysprio;
>>-              BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->dev->dev_addr);
>>+              if (is_zero_ether_addr(bond->params.ad_actor_sys_macaddr))
>>+                      BOND_AD_INFO(bond).system.sys_mac_addr =
>>+                          *((struct mac_addr *)bond->dev->dev_addr);
>>+              else
>>+                      BOND_AD_INFO(bond).system.sys_mac_addr =
>>+                          *((struct mac_addr *)bond->params.ad_actor_sys_macaddr);
>>
>>               /* initialize how many times this module is called in one
>>                * second (should be about every 100ms)
>>diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
>>index 561b2bde5aeb..1a6735ef2ea7 100644
>>--- a/drivers/net/bonding/bond_main.c
>>+++ b/drivers/net/bonding/bond_main.c
>>@@ -4440,6 +4440,7 @@ static int bond_check_params(struct bond_params *params)
>>       params->packets_per_slave = packets_per_slave;
>>       params->tlb_dynamic_lb = 1; /* Default value */
>>       params->ad_actor_sysprio = ad_actor_sysprio;
>>+      eth_zero_addr(params->ad_actor_sys_macaddr);
>>       if (packets_per_slave > 0) {
>>               params->reciprocal_packets_per_slave =
>>                       reciprocal_value(packets_per_slave);
>>diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
>>index d8f6760143ae..330d48b6a1e6 100644
>>--- a/drivers/net/bonding/bond_options.c
>>+++ b/drivers/net/bonding/bond_options.c
>>@@ -72,6 +72,8 @@ static int bond_option_tlb_dynamic_lb_set(struct bonding *bond,
>>                                 const struct bond_opt_value *newval);
>> static int bond_option_ad_actor_sysprio_set(struct bonding *bond,
>>                                 const struct bond_opt_value *newval);
>>+static int bond_option_ad_actor_sys_macaddr_set(struct bonding *bond,
>>+                                const struct bond_opt_value *newval);
>>
>>
>> static const struct bond_opt_value bond_mode_tbl[] = {
>>@@ -396,6 +398,13 @@ static const struct bond_option bond_opts[BOND_OPT_LAST] = {
>>               .values = bond_ad_actor_sysprio_tbl,
>>               .set = bond_option_ad_actor_sysprio_set,
>>       },
>>+      [BOND_OPT_AD_ACTOR_SYS_MACADDR] = {
>>+              .id = BOND_OPT_AD_ACTOR_SYS_MACADDR,
>>+              .name = "ad_actor_system_mac_address",
>>+              .unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_8023AD)),
>>+              .flags = BOND_OPTFLAG_RAWVAL | BOND_OPTFLAG_IFDOWN,
>>+              .set = bond_option_ad_actor_sys_macaddr_set,
>>+      },
>> };
>>
>> /* Searches for an option by name */
>>@@ -1376,3 +1385,23 @@ static int bond_option_ad_actor_sysprio_set(struct bonding *bond,
>>       bond->params.ad_actor_sysprio = newval->value;
>>       return 0;
>> }
>>+
>>+static int bond_option_ad_actor_sys_macaddr_set(struct bonding *bond,
>>+                                          const struct bond_opt_value *newval)
>>+{
>>+      u8 macaddr[ETH_ALEN];
>>+      int i;
>>+
>>+      i = sscanf(newval->string, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
>>+                 &macaddr[0], &macaddr[1], &macaddr[2],
>>+                 &macaddr[3], &macaddr[4], &macaddr[5]);
>>+
>>+      if (i != ETH_ALEN || !is_valid_ether_addr(macaddr)) {
>>+              netdev_err(bond->dev, "Invalid MAC address.\n");
>>+              return -EINVAL;
>>+      }
>>+
>>+      ether_addr_copy(bond->params.ad_actor_sys_macaddr, macaddr);
>>+
>>+      return 0;
>>+}
>>diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c
>>index 9e33c48886ef..81452ced852f 100644
>>--- a/drivers/net/bonding/bond_procfs.c
>>+++ b/drivers/net/bonding/bond_procfs.c
>>@@ -136,6 +136,8 @@ static void bond_info_show_master(struct seq_file *seq)
>>                          optval->string);
>>               seq_printf(seq, "System priority: %d\n",
>>                               BOND_AD_INFO(bond).system.sys_priority);
>>+              seq_printf(seq, "System MAC address: %pM\n",
>>+                              &BOND_AD_INFO(bond).system.sys_mac_addr);
>>
>>               if (__bond_3ad_get_active_agg_info(bond, &ad_info)) {
>>                       seq_printf(seq, "bond %s has no active aggregator\n",
>>@@ -198,6 +200,8 @@ static void bond_info_show_slave(struct seq_file *seq,
>>                       seq_puts(seq, "details actor lacp pdu:\n");
>>                       seq_printf(seq, "    system priority: %d\n",
>>                                  port->actor_system_priority);
>>+                      seq_printf(seq, "    system mac address: %pM\n",
>>+                                 &port->actor_system);
>>                       seq_printf(seq, "    port key: %d\n",
>>                                  port->actor_oper_port_key);
>>                       seq_printf(seq, "    port priority: %d\n",
>>@@ -210,6 +214,8 @@ static void bond_info_show_slave(struct seq_file *seq,
>>                       seq_puts(seq, "details partner lacp pdu:\n");
>>                       seq_printf(seq, "    system priority: %d\n",
>>                                  port->partner_oper.system_priority);
>>+                      seq_printf(seq, "    system mac address: %pM\n",
>>+                                 &port->partner_oper.system);
>>                       seq_printf(seq, "    oper key: %d\n",
>>                                  port->partner_oper.key);
>>                       seq_printf(seq, "    port priority: %d\n",
>>diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
>>index 4350aa06f867..91713d0b6685 100644
>>--- a/drivers/net/bonding/bond_sysfs.c
>>+++ b/drivers/net/bonding/bond_sysfs.c
>>@@ -706,6 +706,21 @@ static ssize_t bonding_show_ad_actor_sysprio(struct device *d,
>> static DEVICE_ATTR(ad_actor_system_priority, S_IRUGO | S_IWUSR,
>>                  bonding_show_ad_actor_sysprio, bonding_sysfs_store_option);
>>
>>+static ssize_t bonding_show_ad_actor_sys_macaddr(struct device *d,
>>+                                               struct device_attribute *attr,
>>+                                               char *buf)
>>+{
>>+      struct bonding *bond = to_bond(d);
>>+
>>+      if (BOND_MODE(bond) == BOND_MODE_8023AD)
>>+              return sprintf(buf, "%pM\n", bond->params.ad_actor_sys_macaddr);
>>+
>>+      return 0;
>>+}
>>+static DEVICE_ATTR(ad_actor_system_mac_address, S_IRUGO | S_IWUSR,
>>+                 bonding_show_ad_actor_sys_macaddr,
>>+                 bonding_sysfs_store_option);
>>+
>> static struct attribute *per_bond_attrs[] = {
>>       &dev_attr_slaves.attr,
>>       &dev_attr_mode.attr,
>>@@ -740,6 +755,7 @@ static struct attribute *per_bond_attrs[] = {
>>       &dev_attr_packets_per_slave.attr,
>>       &dev_attr_tlb_dynamic_lb.attr,
>>       &dev_attr_ad_actor_system_priority.attr,
>>+      &dev_attr_ad_actor_system_mac_address.attr,
>>       NULL,
>> };
>>
>>diff --git a/include/net/bond_options.h b/include/net/bond_options.h
>>index c2af1db37354..993ef73cd050 100644
>>--- a/include/net/bond_options.h
>>+++ b/include/net/bond_options.h
>>@@ -64,6 +64,7 @@ enum {
>>       BOND_OPT_SLAVES,
>>       BOND_OPT_TLB_DYNAMIC_LB,
>>       BOND_OPT_AD_ACTOR_SYSPRIO,
>>+      BOND_OPT_AD_ACTOR_SYS_MACADDR,
>>       BOND_OPT_LAST
>> };
>>
>>diff --git a/include/net/bonding.h b/include/net/bonding.h
>>index 7a5c79fcf866..cd2092e6bc71 100644
>>--- a/include/net/bonding.h
>>+++ b/include/net/bonding.h
>>@@ -144,6 +144,7 @@ struct bond_params {
>>       int tlb_dynamic_lb;
>>       struct reciprocal_value reciprocal_packets_per_slave;
>>       u16 ad_actor_sysprio;
>>+      u8 ad_actor_sys_macaddr[ETH_ALEN];
>> };
>>
>> struct bond_parm_tbl {
>>--
>>2.2.0.rc0.207.ga3a616c
>>
>
> ---
>         -Jay Vosburgh, jay.vosburgh@canonical.com

^ permalink raw reply

* Re: [PATCH next 5/6] bonding: Allow userspace to set macaddr on bonding-dev
From: Maciej Żenczykowski @ 2015-02-07  1:22 UTC (permalink / raw)
  To: Jay Vosburgh
  Cc: Mahesh Bandewar, Andy Gospodarek, Veaceslav Falico,
	Nikolay Aleksandrov, David Miller, netdev, Eric Dumazet
In-Reply-To: <4192.1423272023@famine>

The bonding master's MAC address is visible to the entire L2 domain
while the LACP frames are link local.

Acked-by: Maciej Żenczykowski <maze@google.com>

^ permalink raw reply

* Re: [PATCH next 1/6] bonding: Verify RX LACPDU has proper dest mac-addr
From: Maciej Żenczykowski @ 2015-02-07  1:21 UTC (permalink / raw)
  To: Mahesh Bandewar
  Cc: Jay Vosburgh, Andy Gospodarek, Veaceslav Falico,
	Nikolay Aleksandrov, David Miller, netdev, Eric Dumazet
In-Reply-To: <1423270307-9139-1-git-send-email-maheshb@google.com>

Acked-by: Maciej Żenczykowski <maze@google.com>

On Fri, Feb 6, 2015 at 4:51 PM, Mahesh Bandewar <maheshb@google.com> wrote:
> The 802.1AX standard states:
> "The DA in LACPDUs is the Slow_Protocols_Multicast address."
>
> This patch enforces that and drops LACPDUs with destination MAC
> addresses other than Slow_Protocols_Multicast address
>
> Signed-off-by: Mahesh Bandewar <maheshb@google.com>
> ---
>  drivers/net/bonding/bond_3ad.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
> index cfc4a9c1000a..9b436696b95e 100644
> --- a/drivers/net/bonding/bond_3ad.c
> +++ b/drivers/net/bonding/bond_3ad.c
> @@ -2485,6 +2485,9 @@ int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond,
>         if (skb->protocol != PKT_TYPE_LACPDU)
>                 return RX_HANDLER_ANOTHER;
>
> +       if (!MAC_ADDRESS_EQUAL(eth_hdr(skb)->h_dest, lacpdu_mcast_addr))
> +               return RX_HANDLER_ANOTHER;
> +
>         lacpdu = skb_header_pointer(skb, 0, sizeof(_lacpdu), &_lacpdu);
>         if (!lacpdu)
>                 return RX_HANDLER_ANOTHER;
> --
> 2.2.0.rc0.207.ga3a616c
>
> --
> 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

^ permalink raw reply

* Re: [PATCH next 5/6] bonding: Allow userspace to set macaddr on bonding-dev
From: Jay Vosburgh @ 2015-02-07  1:20 UTC (permalink / raw)
  To: Mahesh Bandewar
  Cc: Andy Gospodarek, Veaceslav Falico, Nikolay Aleksandrov,
	David Miller, netdev, Eric Dumazet
In-Reply-To: <1423270316-9311-1-git-send-email-maheshb@google.com>

Mahesh Bandewar <maheshb@google.com> wrote:

>This patch allows user-space to set the mac-address on the bonding device.
>This mac-address can not be NULL or a Multicast. If the mac-address is set
>from user-space; kernel will honor it and will not overwrite it. In the
>absense (value from user space); the logic will default to using the
>masters' mac as the mac address for the bonding device.
>
>It can be set using example code below -
>
>   # modprobe bonding mode=4
>   # sys_mac_addr=$(printf '%02x:%02x:%02x:%02x:%02x:%02x' \
>                    $(( (RANDOM & 0xFE) | 0x02 )) \
>                    $(( RANDOM & 0xFF )) \
>                    $(( RANDOM & 0xFF )) \
>                    $(( RANDOM & 0xFF )) \
>                    $(( RANDOM & 0xFF )) \
>                    $(( RANDOM & 0xFF )))
>   # echo $sys_mac_addr > /sys/class/net/bond0/bonding/ad_actor_system_mac_address
>   # echo +eth1 > /sys/class/net/bond0/bonding/slaves
>   ...
>   # ip link set bond0 up

	How is this patch functionally different from setting the
bonding master's MAC address to a particular value prior to adding any
slaves?

	-J

>Signed-off-by: Mahesh Bandewar <maheshb@google.com>
>---
> drivers/net/bonding/bond_3ad.c     |  7 ++++++-
> drivers/net/bonding/bond_main.c    |  1 +
> drivers/net/bonding/bond_options.c | 29 +++++++++++++++++++++++++++++
> drivers/net/bonding/bond_procfs.c  |  6 ++++++
> drivers/net/bonding/bond_sysfs.c   | 16 ++++++++++++++++
> include/net/bond_options.h         |  1 +
> include/net/bonding.h              |  1 +
> 7 files changed, 60 insertions(+), 1 deletion(-)
>
>diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
>index 1177f96194dd..373d3db3809f 100644
>--- a/drivers/net/bonding/bond_3ad.c
>+++ b/drivers/net/bonding/bond_3ad.c
>@@ -1914,7 +1914,12 @@ void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution)
> 
> 		BOND_AD_INFO(bond).system.sys_priority =
> 			bond->params.ad_actor_sysprio;
>-		BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->dev->dev_addr);
>+		if (is_zero_ether_addr(bond->params.ad_actor_sys_macaddr))
>+			BOND_AD_INFO(bond).system.sys_mac_addr =
>+			    *((struct mac_addr *)bond->dev->dev_addr);
>+		else
>+			BOND_AD_INFO(bond).system.sys_mac_addr =
>+			    *((struct mac_addr *)bond->params.ad_actor_sys_macaddr);
> 
> 		/* initialize how many times this module is called in one
> 		 * second (should be about every 100ms)
>diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
>index 561b2bde5aeb..1a6735ef2ea7 100644
>--- a/drivers/net/bonding/bond_main.c
>+++ b/drivers/net/bonding/bond_main.c
>@@ -4440,6 +4440,7 @@ static int bond_check_params(struct bond_params *params)
> 	params->packets_per_slave = packets_per_slave;
> 	params->tlb_dynamic_lb = 1; /* Default value */
> 	params->ad_actor_sysprio = ad_actor_sysprio;
>+	eth_zero_addr(params->ad_actor_sys_macaddr);
> 	if (packets_per_slave > 0) {
> 		params->reciprocal_packets_per_slave =
> 			reciprocal_value(packets_per_slave);
>diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
>index d8f6760143ae..330d48b6a1e6 100644
>--- a/drivers/net/bonding/bond_options.c
>+++ b/drivers/net/bonding/bond_options.c
>@@ -72,6 +72,8 @@ static int bond_option_tlb_dynamic_lb_set(struct bonding *bond,
> 				  const struct bond_opt_value *newval);
> static int bond_option_ad_actor_sysprio_set(struct bonding *bond,
> 				  const struct bond_opt_value *newval);
>+static int bond_option_ad_actor_sys_macaddr_set(struct bonding *bond,
>+				  const struct bond_opt_value *newval);
> 
> 
> static const struct bond_opt_value bond_mode_tbl[] = {
>@@ -396,6 +398,13 @@ static const struct bond_option bond_opts[BOND_OPT_LAST] = {
> 		.values = bond_ad_actor_sysprio_tbl,
> 		.set = bond_option_ad_actor_sysprio_set,
> 	},
>+	[BOND_OPT_AD_ACTOR_SYS_MACADDR] = {
>+		.id = BOND_OPT_AD_ACTOR_SYS_MACADDR,
>+		.name = "ad_actor_system_mac_address",
>+		.unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_8023AD)),
>+		.flags = BOND_OPTFLAG_RAWVAL | BOND_OPTFLAG_IFDOWN,
>+		.set = bond_option_ad_actor_sys_macaddr_set,
>+	},
> };
> 
> /* Searches for an option by name */
>@@ -1376,3 +1385,23 @@ static int bond_option_ad_actor_sysprio_set(struct bonding *bond,
> 	bond->params.ad_actor_sysprio = newval->value;
> 	return 0;
> }
>+
>+static int bond_option_ad_actor_sys_macaddr_set(struct bonding *bond,
>+					    const struct bond_opt_value *newval)
>+{
>+	u8 macaddr[ETH_ALEN];
>+	int i;
>+
>+	i = sscanf(newval->string, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
>+		   &macaddr[0], &macaddr[1], &macaddr[2],
>+		   &macaddr[3], &macaddr[4], &macaddr[5]);
>+
>+	if (i != ETH_ALEN || !is_valid_ether_addr(macaddr)) {
>+		netdev_err(bond->dev, "Invalid MAC address.\n");
>+		return -EINVAL;
>+	}
>+
>+	ether_addr_copy(bond->params.ad_actor_sys_macaddr, macaddr);
>+
>+	return 0;
>+}
>diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c
>index 9e33c48886ef..81452ced852f 100644
>--- a/drivers/net/bonding/bond_procfs.c
>+++ b/drivers/net/bonding/bond_procfs.c
>@@ -136,6 +136,8 @@ static void bond_info_show_master(struct seq_file *seq)
> 			   optval->string);
> 		seq_printf(seq, "System priority: %d\n",
> 				BOND_AD_INFO(bond).system.sys_priority);
>+		seq_printf(seq, "System MAC address: %pM\n",
>+				&BOND_AD_INFO(bond).system.sys_mac_addr);
> 
> 		if (__bond_3ad_get_active_agg_info(bond, &ad_info)) {
> 			seq_printf(seq, "bond %s has no active aggregator\n",
>@@ -198,6 +200,8 @@ static void bond_info_show_slave(struct seq_file *seq,
> 			seq_puts(seq, "details actor lacp pdu:\n");
> 			seq_printf(seq, "    system priority: %d\n",
> 				   port->actor_system_priority);
>+			seq_printf(seq, "    system mac address: %pM\n",
>+				   &port->actor_system);
> 			seq_printf(seq, "    port key: %d\n",
> 				   port->actor_oper_port_key);
> 			seq_printf(seq, "    port priority: %d\n",
>@@ -210,6 +214,8 @@ static void bond_info_show_slave(struct seq_file *seq,
> 			seq_puts(seq, "details partner lacp pdu:\n");
> 			seq_printf(seq, "    system priority: %d\n",
> 				   port->partner_oper.system_priority);
>+			seq_printf(seq, "    system mac address: %pM\n",
>+				   &port->partner_oper.system);
> 			seq_printf(seq, "    oper key: %d\n",
> 				   port->partner_oper.key);
> 			seq_printf(seq, "    port priority: %d\n",
>diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
>index 4350aa06f867..91713d0b6685 100644
>--- a/drivers/net/bonding/bond_sysfs.c
>+++ b/drivers/net/bonding/bond_sysfs.c
>@@ -706,6 +706,21 @@ static ssize_t bonding_show_ad_actor_sysprio(struct device *d,
> static DEVICE_ATTR(ad_actor_system_priority, S_IRUGO | S_IWUSR,
> 		   bonding_show_ad_actor_sysprio, bonding_sysfs_store_option);
> 
>+static ssize_t bonding_show_ad_actor_sys_macaddr(struct device *d,
>+						 struct device_attribute *attr,
>+						 char *buf)
>+{
>+	struct bonding *bond = to_bond(d);
>+
>+	if (BOND_MODE(bond) == BOND_MODE_8023AD)
>+		return sprintf(buf, "%pM\n", bond->params.ad_actor_sys_macaddr);
>+
>+	return 0;
>+}
>+static DEVICE_ATTR(ad_actor_system_mac_address, S_IRUGO | S_IWUSR,
>+		   bonding_show_ad_actor_sys_macaddr,
>+		   bonding_sysfs_store_option);
>+
> static struct attribute *per_bond_attrs[] = {
> 	&dev_attr_slaves.attr,
> 	&dev_attr_mode.attr,
>@@ -740,6 +755,7 @@ static struct attribute *per_bond_attrs[] = {
> 	&dev_attr_packets_per_slave.attr,
> 	&dev_attr_tlb_dynamic_lb.attr,
> 	&dev_attr_ad_actor_system_priority.attr,
>+	&dev_attr_ad_actor_system_mac_address.attr,
> 	NULL,
> };
> 
>diff --git a/include/net/bond_options.h b/include/net/bond_options.h
>index c2af1db37354..993ef73cd050 100644
>--- a/include/net/bond_options.h
>+++ b/include/net/bond_options.h
>@@ -64,6 +64,7 @@ enum {
> 	BOND_OPT_SLAVES,
> 	BOND_OPT_TLB_DYNAMIC_LB,
> 	BOND_OPT_AD_ACTOR_SYSPRIO,
>+	BOND_OPT_AD_ACTOR_SYS_MACADDR,
> 	BOND_OPT_LAST
> };
> 
>diff --git a/include/net/bonding.h b/include/net/bonding.h
>index 7a5c79fcf866..cd2092e6bc71 100644
>--- a/include/net/bonding.h
>+++ b/include/net/bonding.h
>@@ -144,6 +144,7 @@ struct bond_params {
> 	int tlb_dynamic_lb;
> 	struct reciprocal_value reciprocal_packets_per_slave;
> 	u16 ad_actor_sysprio;
>+	u8 ad_actor_sys_macaddr[ETH_ALEN];
> };
> 
> struct bond_parm_tbl {
>-- 
>2.2.0.rc0.207.ga3a616c
>

---
	-Jay Vosburgh, jay.vosburgh@canonical.com

^ permalink raw reply

* [PATCH next 1/6] bonding: Verify RX LACPDU has proper dest mac-addr
From: Mahesh Bandewar @ 2015-02-07  0:51 UTC (permalink / raw)
  To: Jay Vosburgh, Andy Gospodarek, Veaceslav Falico,
	Nikolay Aleksandrov, David Miller
  Cc: Mahesh Bandewar, netdev, Eric Dumazet

The 802.1AX standard states:
"The DA in LACPDUs is the Slow_Protocols_Multicast address."

This patch enforces that and drops LACPDUs with destination MAC
addresses other than Slow_Protocols_Multicast address

Signed-off-by: Mahesh Bandewar <maheshb@google.com>
---
 drivers/net/bonding/bond_3ad.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index cfc4a9c1000a..9b436696b95e 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2485,6 +2485,9 @@ int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond,
 	if (skb->protocol != PKT_TYPE_LACPDU)
 		return RX_HANDLER_ANOTHER;
 
+	if (!MAC_ADDRESS_EQUAL(eth_hdr(skb)->h_dest, lacpdu_mcast_addr))
+		return RX_HANDLER_ANOTHER;
+
 	lacpdu = skb_header_pointer(skb, 0, sizeof(_lacpdu), &_lacpdu);
 	if (!lacpdu)
 		return RX_HANDLER_ANOTHER;
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related

* [PATCH next 6/6] bonding: Implement user key part of port_key in an AD system.
From: Mahesh Bandewar @ 2015-02-07  0:51 UTC (permalink / raw)
  To: Jay Vosburgh, Andy Gospodarek, Veaceslav Falico,
	Nikolay Aleksandrov, David Miller
  Cc: Mahesh Bandewar, netdev, Eric Dumazet

The port key has three components - user-key, speed-part, and duplex-part.
The LSBit is for the duplex-part, next 5 bits are for the speed while the
remaining 10 bits are the user defined key bits. Get these 10 bits
from the user-space (through the SysFs interface) and use it to form the
admin port-key. Allowed range for the user-key is 0 - 1023 (10 bits). If
it is not provided then use zero for the user-key-bits (default).

It can set using following example code -

   # modprobe bonding mode=4
   # usr_port_key=$(( RANDOM & 0x3FF ))
   # echo $usr_port_key > /sys/class/net/bond0/bonding/ad_actor_user_port_key
   # echo +eth1 > /sys/class/net/bond0/bonding/slaves
   ...
   # ip link set bond0 up

Signed-off-by: Mahesh Bandewar <maheshb@google.com>
---
 drivers/net/bonding/bond_3ad.c     |  6 +++---
 drivers/net/bonding/bond_main.c    | 10 ++++++++++
 drivers/net/bonding/bond_options.c | 26 ++++++++++++++++++++++++++
 drivers/net/bonding/bond_sysfs.c   | 15 +++++++++++++++
 include/net/bond_options.h         |  1 +
 include/net/bonding.h              |  1 +
 6 files changed, 56 insertions(+), 3 deletions(-)

diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 373d3db3809f..c69c393ba8c5 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -1955,10 +1955,10 @@ void bond_3ad_bind_slave(struct slave *slave)
 
 		port->slave = slave;
 		port->actor_port_number = SLAVE_AD_INFO(slave)->id;
-		/* key is determined according to the link speed, duplex and user key(which
-		 * is yet not supported)
+		/* key is determined according to the link speed, duplex and
+		 * user key
 		 */
-		port->actor_admin_port_key = 0;
+		port->actor_admin_port_key = bond->params.ad_actor_portkey << 6;
 		port->actor_admin_port_key |= __get_duplex(port);
 		port->actor_admin_port_key |= (__get_link_speed(port) << 1);
 		port->actor_oper_port_key = port->actor_admin_port_key;
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 1a6735ef2ea7..f9f001f35a91 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4105,6 +4105,7 @@ static int bond_check_params(struct bond_params *params)
 	const struct bond_opt_value *valptr;
 	int arp_all_targets_value;
 	u16 ad_actor_sysprio = 0;
+	u16 ad_actor_portkey = 0;
 
 	/* Convert string parameters. */
 	if (mode) {
@@ -4409,6 +4410,14 @@ static int bond_check_params(struct bond_params *params)
 			return -EINVAL;
 		}
 		ad_actor_sysprio = valptr->value;
+
+		valptr = bond_opt_parse(bond_opt_get(BOND_OPT_AD_ACTOR_PORTKEY),
+					&newval);
+		if (!valptr) {
+			pr_err("Error: No ad_actor_portkey default value");
+			return -EINVAL;
+		}
+		ad_actor_portkey = valptr->value;
 	}
 
 	if (lp_interval == 0) {
@@ -4441,6 +4450,7 @@ static int bond_check_params(struct bond_params *params)
 	params->tlb_dynamic_lb = 1; /* Default value */
 	params->ad_actor_sysprio = ad_actor_sysprio;
 	eth_zero_addr(params->ad_actor_sys_macaddr);
+	params->ad_actor_portkey = ad_actor_portkey;
 	if (packets_per_slave > 0) {
 		params->reciprocal_packets_per_slave =
 			reciprocal_value(packets_per_slave);
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
index 330d48b6a1e6..c3f77c6d0d2e 100644
--- a/drivers/net/bonding/bond_options.c
+++ b/drivers/net/bonding/bond_options.c
@@ -74,6 +74,8 @@ static int bond_option_ad_actor_sysprio_set(struct bonding *bond,
 				  const struct bond_opt_value *newval);
 static int bond_option_ad_actor_sys_macaddr_set(struct bonding *bond,
 				  const struct bond_opt_value *newval);
+static int bond_option_ad_actor_portkey_set(struct bonding *bond,
+				  const struct bond_opt_value *newval);
 
 
 static const struct bond_opt_value bond_mode_tbl[] = {
@@ -196,6 +198,12 @@ static const struct bond_opt_value bond_ad_actor_sysprio_tbl[] = {
 	{ NULL,      -1,    0},
 };
 
+static const struct bond_opt_value bond_ad_actor_portkey_tbl[] = {
+	{ "minval",  0,     BOND_VALFLAG_MIN | BOND_VALFLAG_DEFAULT},
+	{ "maxval",  1023,  BOND_VALFLAG_MAX},
+	{ NULL,      -1,    0},
+};
+
 static const struct bond_option bond_opts[BOND_OPT_LAST] = {
 	[BOND_OPT_MODE] = {
 		.id = BOND_OPT_MODE,
@@ -405,6 +413,14 @@ static const struct bond_option bond_opts[BOND_OPT_LAST] = {
 		.flags = BOND_OPTFLAG_RAWVAL | BOND_OPTFLAG_IFDOWN,
 		.set = bond_option_ad_actor_sys_macaddr_set,
 	},
+	[BOND_OPT_AD_ACTOR_PORTKEY] = {
+		.id = BOND_OPT_AD_ACTOR_PORTKEY,
+		.name = "ad_actor_user_port_key",
+		.unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_8023AD)),
+		.flags = BOND_OPTFLAG_IFDOWN,
+		.values = bond_ad_actor_portkey_tbl,
+		.set = bond_option_ad_actor_portkey_set,
+	}
 };
 
 /* Searches for an option by name */
@@ -1405,3 +1421,13 @@ static int bond_option_ad_actor_sys_macaddr_set(struct bonding *bond,
 
 	return 0;
 }
+
+static int bond_option_ad_actor_portkey_set(struct bonding *bond,
+					    const struct bond_opt_value *newval)
+{
+	netdev_info(bond->dev, "Setting ad_actor_portkey to (%llu)\n",
+		    newval->value);
+
+	bond->params.ad_actor_portkey = newval->value;
+	return 0;
+}
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 91713d0b6685..17d84d5a1608 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -721,6 +721,20 @@ static DEVICE_ATTR(ad_actor_system_mac_address, S_IRUGO | S_IWUSR,
 		   bonding_show_ad_actor_sys_macaddr,
 		   bonding_sysfs_store_option);
 
+static ssize_t bonding_show_ad_actor_portkey(struct device *d,
+					     struct device_attribute *attr,
+					     char *buf)
+{
+	struct bonding *bond = to_bond(d);
+
+	if (BOND_MODE(bond) == BOND_MODE_8023AD)
+		return sprintf(buf, "%hu\n", bond->params.ad_actor_portkey);
+
+	return 0;
+}
+static DEVICE_ATTR(ad_actor_user_port_key, S_IRUGO | S_IWUSR,
+		   bonding_show_ad_actor_portkey, bonding_sysfs_store_option);
+
 static struct attribute *per_bond_attrs[] = {
 	&dev_attr_slaves.attr,
 	&dev_attr_mode.attr,
@@ -756,6 +770,7 @@ static struct attribute *per_bond_attrs[] = {
 	&dev_attr_tlb_dynamic_lb.attr,
 	&dev_attr_ad_actor_system_priority.attr,
 	&dev_attr_ad_actor_system_mac_address.attr,
+	&dev_attr_ad_actor_user_port_key.attr,
 	NULL,
 };
 
diff --git a/include/net/bond_options.h b/include/net/bond_options.h
index 993ef73cd050..4c36455aacb4 100644
--- a/include/net/bond_options.h
+++ b/include/net/bond_options.h
@@ -65,6 +65,7 @@ enum {
 	BOND_OPT_TLB_DYNAMIC_LB,
 	BOND_OPT_AD_ACTOR_SYSPRIO,
 	BOND_OPT_AD_ACTOR_SYS_MACADDR,
+	BOND_OPT_AD_ACTOR_PORTKEY,
 	BOND_OPT_LAST
 };
 
diff --git a/include/net/bonding.h b/include/net/bonding.h
index cd2092e6bc71..e91db2566437 100644
--- a/include/net/bonding.h
+++ b/include/net/bonding.h
@@ -144,6 +144,7 @@ struct bond_params {
 	int tlb_dynamic_lb;
 	struct reciprocal_value reciprocal_packets_per_slave;
 	u16 ad_actor_sysprio;
+	u16 ad_actor_portkey;
 	u8 ad_actor_sys_macaddr[ETH_ALEN];
 };
 
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related

* [PATCH next 5/6] bonding: Allow userspace to set macaddr on bonding-dev
From: Mahesh Bandewar @ 2015-02-07  0:51 UTC (permalink / raw)
  To: Jay Vosburgh, Andy Gospodarek, Veaceslav Falico,
	Nikolay Aleksandrov, David Miller
  Cc: Mahesh Bandewar, netdev, Eric Dumazet

This patch allows user-space to set the mac-address on the bonding device.
This mac-address can not be NULL or a Multicast. If the mac-address is set
from user-space; kernel will honor it and will not overwrite it. In the
absense (value from user space); the logic will default to using the
masters' mac as the mac address for the bonding device.

It can be set using example code below -

   # modprobe bonding mode=4
   # sys_mac_addr=$(printf '%02x:%02x:%02x:%02x:%02x:%02x' \
                    $(( (RANDOM & 0xFE) | 0x02 )) \
                    $(( RANDOM & 0xFF )) \
                    $(( RANDOM & 0xFF )) \
                    $(( RANDOM & 0xFF )) \
                    $(( RANDOM & 0xFF )) \
                    $(( RANDOM & 0xFF )))
   # echo $sys_mac_addr > /sys/class/net/bond0/bonding/ad_actor_system_mac_address
   # echo +eth1 > /sys/class/net/bond0/bonding/slaves
   ...
   # ip link set bond0 up

Signed-off-by: Mahesh Bandewar <maheshb@google.com>
---
 drivers/net/bonding/bond_3ad.c     |  7 ++++++-
 drivers/net/bonding/bond_main.c    |  1 +
 drivers/net/bonding/bond_options.c | 29 +++++++++++++++++++++++++++++
 drivers/net/bonding/bond_procfs.c  |  6 ++++++
 drivers/net/bonding/bond_sysfs.c   | 16 ++++++++++++++++
 include/net/bond_options.h         |  1 +
 include/net/bonding.h              |  1 +
 7 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 1177f96194dd..373d3db3809f 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -1914,7 +1914,12 @@ void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution)
 
 		BOND_AD_INFO(bond).system.sys_priority =
 			bond->params.ad_actor_sysprio;
-		BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->dev->dev_addr);
+		if (is_zero_ether_addr(bond->params.ad_actor_sys_macaddr))
+			BOND_AD_INFO(bond).system.sys_mac_addr =
+			    *((struct mac_addr *)bond->dev->dev_addr);
+		else
+			BOND_AD_INFO(bond).system.sys_mac_addr =
+			    *((struct mac_addr *)bond->params.ad_actor_sys_macaddr);
 
 		/* initialize how many times this module is called in one
 		 * second (should be about every 100ms)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 561b2bde5aeb..1a6735ef2ea7 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4440,6 +4440,7 @@ static int bond_check_params(struct bond_params *params)
 	params->packets_per_slave = packets_per_slave;
 	params->tlb_dynamic_lb = 1; /* Default value */
 	params->ad_actor_sysprio = ad_actor_sysprio;
+	eth_zero_addr(params->ad_actor_sys_macaddr);
 	if (packets_per_slave > 0) {
 		params->reciprocal_packets_per_slave =
 			reciprocal_value(packets_per_slave);
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
index d8f6760143ae..330d48b6a1e6 100644
--- a/drivers/net/bonding/bond_options.c
+++ b/drivers/net/bonding/bond_options.c
@@ -72,6 +72,8 @@ static int bond_option_tlb_dynamic_lb_set(struct bonding *bond,
 				  const struct bond_opt_value *newval);
 static int bond_option_ad_actor_sysprio_set(struct bonding *bond,
 				  const struct bond_opt_value *newval);
+static int bond_option_ad_actor_sys_macaddr_set(struct bonding *bond,
+				  const struct bond_opt_value *newval);
 
 
 static const struct bond_opt_value bond_mode_tbl[] = {
@@ -396,6 +398,13 @@ static const struct bond_option bond_opts[BOND_OPT_LAST] = {
 		.values = bond_ad_actor_sysprio_tbl,
 		.set = bond_option_ad_actor_sysprio_set,
 	},
+	[BOND_OPT_AD_ACTOR_SYS_MACADDR] = {
+		.id = BOND_OPT_AD_ACTOR_SYS_MACADDR,
+		.name = "ad_actor_system_mac_address",
+		.unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_8023AD)),
+		.flags = BOND_OPTFLAG_RAWVAL | BOND_OPTFLAG_IFDOWN,
+		.set = bond_option_ad_actor_sys_macaddr_set,
+	},
 };
 
 /* Searches for an option by name */
@@ -1376,3 +1385,23 @@ static int bond_option_ad_actor_sysprio_set(struct bonding *bond,
 	bond->params.ad_actor_sysprio = newval->value;
 	return 0;
 }
+
+static int bond_option_ad_actor_sys_macaddr_set(struct bonding *bond,
+					    const struct bond_opt_value *newval)
+{
+	u8 macaddr[ETH_ALEN];
+	int i;
+
+	i = sscanf(newval->string, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
+		   &macaddr[0], &macaddr[1], &macaddr[2],
+		   &macaddr[3], &macaddr[4], &macaddr[5]);
+
+	if (i != ETH_ALEN || !is_valid_ether_addr(macaddr)) {
+		netdev_err(bond->dev, "Invalid MAC address.\n");
+		return -EINVAL;
+	}
+
+	ether_addr_copy(bond->params.ad_actor_sys_macaddr, macaddr);
+
+	return 0;
+}
diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c
index 9e33c48886ef..81452ced852f 100644
--- a/drivers/net/bonding/bond_procfs.c
+++ b/drivers/net/bonding/bond_procfs.c
@@ -136,6 +136,8 @@ static void bond_info_show_master(struct seq_file *seq)
 			   optval->string);
 		seq_printf(seq, "System priority: %d\n",
 				BOND_AD_INFO(bond).system.sys_priority);
+		seq_printf(seq, "System MAC address: %pM\n",
+				&BOND_AD_INFO(bond).system.sys_mac_addr);
 
 		if (__bond_3ad_get_active_agg_info(bond, &ad_info)) {
 			seq_printf(seq, "bond %s has no active aggregator\n",
@@ -198,6 +200,8 @@ static void bond_info_show_slave(struct seq_file *seq,
 			seq_puts(seq, "details actor lacp pdu:\n");
 			seq_printf(seq, "    system priority: %d\n",
 				   port->actor_system_priority);
+			seq_printf(seq, "    system mac address: %pM\n",
+				   &port->actor_system);
 			seq_printf(seq, "    port key: %d\n",
 				   port->actor_oper_port_key);
 			seq_printf(seq, "    port priority: %d\n",
@@ -210,6 +214,8 @@ static void bond_info_show_slave(struct seq_file *seq,
 			seq_puts(seq, "details partner lacp pdu:\n");
 			seq_printf(seq, "    system priority: %d\n",
 				   port->partner_oper.system_priority);
+			seq_printf(seq, "    system mac address: %pM\n",
+				   &port->partner_oper.system);
 			seq_printf(seq, "    oper key: %d\n",
 				   port->partner_oper.key);
 			seq_printf(seq, "    port priority: %d\n",
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 4350aa06f867..91713d0b6685 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -706,6 +706,21 @@ static ssize_t bonding_show_ad_actor_sysprio(struct device *d,
 static DEVICE_ATTR(ad_actor_system_priority, S_IRUGO | S_IWUSR,
 		   bonding_show_ad_actor_sysprio, bonding_sysfs_store_option);
 
+static ssize_t bonding_show_ad_actor_sys_macaddr(struct device *d,
+						 struct device_attribute *attr,
+						 char *buf)
+{
+	struct bonding *bond = to_bond(d);
+
+	if (BOND_MODE(bond) == BOND_MODE_8023AD)
+		return sprintf(buf, "%pM\n", bond->params.ad_actor_sys_macaddr);
+
+	return 0;
+}
+static DEVICE_ATTR(ad_actor_system_mac_address, S_IRUGO | S_IWUSR,
+		   bonding_show_ad_actor_sys_macaddr,
+		   bonding_sysfs_store_option);
+
 static struct attribute *per_bond_attrs[] = {
 	&dev_attr_slaves.attr,
 	&dev_attr_mode.attr,
@@ -740,6 +755,7 @@ static struct attribute *per_bond_attrs[] = {
 	&dev_attr_packets_per_slave.attr,
 	&dev_attr_tlb_dynamic_lb.attr,
 	&dev_attr_ad_actor_system_priority.attr,
+	&dev_attr_ad_actor_system_mac_address.attr,
 	NULL,
 };
 
diff --git a/include/net/bond_options.h b/include/net/bond_options.h
index c2af1db37354..993ef73cd050 100644
--- a/include/net/bond_options.h
+++ b/include/net/bond_options.h
@@ -64,6 +64,7 @@ enum {
 	BOND_OPT_SLAVES,
 	BOND_OPT_TLB_DYNAMIC_LB,
 	BOND_OPT_AD_ACTOR_SYSPRIO,
+	BOND_OPT_AD_ACTOR_SYS_MACADDR,
 	BOND_OPT_LAST
 };
 
diff --git a/include/net/bonding.h b/include/net/bonding.h
index 7a5c79fcf866..cd2092e6bc71 100644
--- a/include/net/bonding.h
+++ b/include/net/bonding.h
@@ -144,6 +144,7 @@ struct bond_params {
 	int tlb_dynamic_lb;
 	struct reciprocal_value reciprocal_packets_per_slave;
 	u16 ad_actor_sysprio;
+	u8 ad_actor_sys_macaddr[ETH_ALEN];
 };
 
 struct bond_parm_tbl {
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related

* [PATCH next 4/6] bonding: Allow userspace to set system_priority
From: Mahesh Bandewar @ 2015-02-07  0:51 UTC (permalink / raw)
  To: Jay Vosburgh, Andy Gospodarek, Veaceslav Falico,
	Nikolay Aleksandrov, David Miller
  Cc: Mahesh Bandewar, netdev, Eric Dumazet

This patch allows user to randomize the system-priority in an ad-system.
The allowed range is 1 - 0xFFFF while default value is 0xFFFF. If user
does not specify this value, the system defaults to 0xFFFF, which is
what it was before this patch.

Following example code could set the value -
    # modprobe bonding mode=4
    # sys_prio=$(( 1 + RANDOM + RANDOM ))
    # echo $sys_prio > /sys/class/net/bond0/bonding/ad_actor_system_priority
    # echo +eth1 > /sys/class/net/bond0/bonding/slaves
    ...
    # ip link set bond0 up

Signed-off-by: Mahesh Bandewar <maheshb@google.com>
---
 drivers/net/bonding/bond_3ad.c     |  5 ++++-
 drivers/net/bonding/bond_main.c    | 14 ++++++++++++++
 drivers/net/bonding/bond_options.c | 29 ++++++++++++++++++++++++++++-
 drivers/net/bonding/bond_procfs.c  |  2 ++
 drivers/net/bonding/bond_sysfs.c   | 15 +++++++++++++++
 include/net/bond_options.h         |  1 +
 include/net/bonding.h              |  1 +
 7 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 2a69095266c1..1177f96194dd 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -1912,7 +1912,8 @@ void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution)
 
 		BOND_AD_INFO(bond).aggregator_identifier = 0;
 
-		BOND_AD_INFO(bond).system.sys_priority = 0xFFFF;
+		BOND_AD_INFO(bond).system.sys_priority =
+			bond->params.ad_actor_sysprio;
 		BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->dev->dev_addr);
 
 		/* initialize how many times this module is called in one
@@ -1963,6 +1964,8 @@ void bond_3ad_bind_slave(struct slave *slave)
 			port->sm_vars &= ~AD_PORT_LACP_ENABLED;
 		/* actor system is the bond's system */
 		port->actor_system = BOND_AD_INFO(bond).system.sys_mac_addr;
+		port->actor_system_priority =
+		    BOND_AD_INFO(bond).system.sys_priority;
 		/* tx timer(to verify that no more than MAX_TX_IN_SECOND
 		 * lacpdu's are sent in one second)
 		 */
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index a50ec87486f3..561b2bde5aeb 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4104,6 +4104,7 @@ static int bond_check_params(struct bond_params *params)
 	struct bond_opt_value newval;
 	const struct bond_opt_value *valptr;
 	int arp_all_targets_value;
+	u16 ad_actor_sysprio = 0;
 
 	/* Convert string parameters. */
 	if (mode) {
@@ -4398,6 +4399,18 @@ static int bond_check_params(struct bond_params *params)
 		fail_over_mac_value = BOND_FOM_NONE;
 	}
 
+	if (bond_mode == BOND_MODE_8023AD) {
+		bond_opt_initstr(&newval, "default");
+		valptr = bond_opt_parse(
+				bond_opt_get(BOND_OPT_AD_ACTOR_SYSPRIO),
+					     &newval);
+		if (!valptr) {
+			pr_err("Error: No ad_actor_sysprio default value");
+			return -EINVAL;
+		}
+		ad_actor_sysprio = valptr->value;
+	}
+
 	if (lp_interval == 0) {
 		pr_warn("Warning: ip_interval must be between 1 and %d, so it was reset to %d\n",
 			INT_MAX, BOND_ALB_DEFAULT_LP_INTERVAL);
@@ -4426,6 +4439,7 @@ static int bond_check_params(struct bond_params *params)
 	params->lp_interval = lp_interval;
 	params->packets_per_slave = packets_per_slave;
 	params->tlb_dynamic_lb = 1; /* Default value */
+	params->ad_actor_sysprio = ad_actor_sysprio;
 	if (packets_per_slave > 0) {
 		params->reciprocal_packets_per_slave =
 			reciprocal_value(packets_per_slave);
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
index 4df28943d222..d8f6760143ae 100644
--- a/drivers/net/bonding/bond_options.c
+++ b/drivers/net/bonding/bond_options.c
@@ -70,6 +70,8 @@ static int bond_option_slaves_set(struct bonding *bond,
 				  const struct bond_opt_value *newval);
 static int bond_option_tlb_dynamic_lb_set(struct bonding *bond,
 				  const struct bond_opt_value *newval);
+static int bond_option_ad_actor_sysprio_set(struct bonding *bond,
+				  const struct bond_opt_value *newval);
 
 
 static const struct bond_opt_value bond_mode_tbl[] = {
@@ -186,6 +188,12 @@ static const struct bond_opt_value bond_tlb_dynamic_lb_tbl[] = {
 	{ NULL,  -1, 0}
 };
 
+static const struct bond_opt_value bond_ad_actor_sysprio_tbl[] = {
+	{ "minval",  1,     BOND_VALFLAG_MIN},
+	{ "maxval",  65535, BOND_VALFLAG_MAX | BOND_VALFLAG_DEFAULT},
+	{ NULL,      -1,    0},
+};
+
 static const struct bond_option bond_opts[BOND_OPT_LAST] = {
 	[BOND_OPT_MODE] = {
 		.id = BOND_OPT_MODE,
@@ -379,7 +387,15 @@ static const struct bond_option bond_opts[BOND_OPT_LAST] = {
 		.values = bond_tlb_dynamic_lb_tbl,
 		.flags = BOND_OPTFLAG_IFDOWN,
 		.set = bond_option_tlb_dynamic_lb_set,
-	}
+	},
+	[BOND_OPT_AD_ACTOR_SYSPRIO] = {
+		.id = BOND_OPT_AD_ACTOR_SYSPRIO,
+		.name = "ad_actor_system_priority",
+		.unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_8023AD)),
+		.flags = BOND_OPTFLAG_IFDOWN,
+		.values = bond_ad_actor_sysprio_tbl,
+		.set = bond_option_ad_actor_sysprio_set,
+	},
 };
 
 /* Searches for an option by name */
@@ -1349,3 +1365,14 @@ static int bond_option_tlb_dynamic_lb_set(struct bonding *bond,
 
 	return 0;
 }
+
+
+static int bond_option_ad_actor_sysprio_set(struct bonding *bond,
+					    const struct bond_opt_value *newval)
+{
+	netdev_info(bond->dev, "Setting ad_actor_sysprio to (%llu)\n",
+		    newval->value);
+
+	bond->params.ad_actor_sysprio = newval->value;
+	return 0;
+}
diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c
index 83095a0b4b90..9e33c48886ef 100644
--- a/drivers/net/bonding/bond_procfs.c
+++ b/drivers/net/bonding/bond_procfs.c
@@ -134,6 +134,8 @@ static void bond_info_show_master(struct seq_file *seq)
 					  bond->params.ad_select);
 		seq_printf(seq, "Aggregator selection policy (ad_select): %s\n",
 			   optval->string);
+		seq_printf(seq, "System priority: %d\n",
+				BOND_AD_INFO(bond).system.sys_priority);
 
 		if (__bond_3ad_get_active_agg_info(bond, &ad_info)) {
 			seq_printf(seq, "bond %s has no active aggregator\n",
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 7e9e151d4d61..4350aa06f867 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -692,6 +692,20 @@ static ssize_t bonding_show_packets_per_slave(struct device *d,
 static DEVICE_ATTR(packets_per_slave, S_IRUGO | S_IWUSR,
 		   bonding_show_packets_per_slave, bonding_sysfs_store_option);
 
+static ssize_t bonding_show_ad_actor_sysprio(struct device *d,
+					     struct device_attribute *attr,
+					     char *buf)
+{
+	struct bonding *bond = to_bond(d);
+
+	if (BOND_MODE(bond) == BOND_MODE_8023AD)
+		return sprintf(buf, "%hu\n", bond->params.ad_actor_sysprio);
+
+	return 0;
+}
+static DEVICE_ATTR(ad_actor_system_priority, S_IRUGO | S_IWUSR,
+		   bonding_show_ad_actor_sysprio, bonding_sysfs_store_option);
+
 static struct attribute *per_bond_attrs[] = {
 	&dev_attr_slaves.attr,
 	&dev_attr_mode.attr,
@@ -725,6 +739,7 @@ static struct attribute *per_bond_attrs[] = {
 	&dev_attr_lp_interval.attr,
 	&dev_attr_packets_per_slave.attr,
 	&dev_attr_tlb_dynamic_lb.attr,
+	&dev_attr_ad_actor_system_priority.attr,
 	NULL,
 };
 
diff --git a/include/net/bond_options.h b/include/net/bond_options.h
index ea6546d2c946..c2af1db37354 100644
--- a/include/net/bond_options.h
+++ b/include/net/bond_options.h
@@ -63,6 +63,7 @@ enum {
 	BOND_OPT_LP_INTERVAL,
 	BOND_OPT_SLAVES,
 	BOND_OPT_TLB_DYNAMIC_LB,
+	BOND_OPT_AD_ACTOR_SYSPRIO,
 	BOND_OPT_LAST
 };
 
diff --git a/include/net/bonding.h b/include/net/bonding.h
index 29f53eacac0a..7a5c79fcf866 100644
--- a/include/net/bonding.h
+++ b/include/net/bonding.h
@@ -143,6 +143,7 @@ struct bond_params {
 	int packets_per_slave;
 	int tlb_dynamic_lb;
 	struct reciprocal_value reciprocal_packets_per_slave;
+	u16 ad_actor_sysprio;
 };
 
 struct bond_parm_tbl {
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related

* [PATCH next 3/6] bonding: Implement port churn-machine (AD standard 43.4.17).
From: Mahesh Bandewar @ 2015-02-07  0:51 UTC (permalink / raw)
  To: Jay Vosburgh, Andy Gospodarek, Veaceslav Falico,
	Nikolay Aleksandrov, David Miller
  Cc: Mahesh Bandewar, netdev, Eric Dumazet

The Chrun Detection machines detect the situation where a port is operable,
but the Actor and Partner have not attached the link to an Aggregator and
brought the link into operation within a bound time period. Under normal
operation of the LACP, aggrement between Actor and Partner should be reached
very rapidly. Continued failure to reach aggrement can be symptomatic of
device failure.

Actor-churn-dection state-machine
=================================

BEGIN=True + PortEnable=False
           |
           v
 +------------------------+   ActorPort.Sync=True  +------------------+
 |   ACTOR_CHURN_MONITOR  | ---------------------> |  NO_ACTOR_CHURN  |
 |========================|                        |==================|
 |    ActorChurn=False    |  ActorPort.Sync=False  | ActorChurn=False |
 | ActorChurn.Timer=Start | <--------------------- |                  |
 +------------------------+                        +------------------+
           |                                                ^
           |                                                |
  ActorChurn.Timer=Expired                                  |
           |                                       ActorPort.Sync=True
           |                                                |
           |                +-----------------+             |
           |                |   ACTOR_CHURN   |             |
           |                |=================|             |
           +--------------> | ActorChurn=True | ------------+
                            |                 |
                            +-----------------+

Similar for the Partner-churn-detection.

Signed-off-by: Mahesh Bandewar <maheshb@google.com>
---
 drivers/net/bonding/bond_3ad.c    | 56 +++++++++++++++++++++++++++++++++++++--
 drivers/net/bonding/bond_procfs.c | 40 +++++++++++++++++++++++++---
 include/net/bond_3ad.h            | 29 ++++++++++++++++++++
 3 files changed, 119 insertions(+), 6 deletions(-)

diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 14f2ebe786c5..2a69095266c1 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -38,6 +38,7 @@
 #define AD_STANDBY                 0x2
 #define AD_MAX_TX_IN_SECOND        3
 #define AD_COLLECTOR_MAX_DELAY     0
+#define AD_MONITOR_CHURNED         0x1000
 
 /* Timer definitions (43.4.4 in the 802.3ad standard) */
 #define AD_FAST_PERIODIC_TIME      1
@@ -1013,16 +1014,19 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
 	/* check if state machine should change state */
 
 	/* first, check if port was reinitialized */
-	if (port->sm_vars & AD_PORT_BEGIN)
+	if (port->sm_vars & AD_PORT_BEGIN) {
 		port->sm_rx_state = AD_RX_INITIALIZE;
+		port->sm_vars |= AD_MONITOR_CHURNED;
 	/* check if port is not enabled */
-	else if (!(port->sm_vars & AD_PORT_BEGIN)
+	} else if (!(port->sm_vars & AD_PORT_BEGIN)
 		 && !port->is_enabled && !(port->sm_vars & AD_PORT_MOVED))
 		port->sm_rx_state = AD_RX_PORT_DISABLED;
 	/* check if new lacpdu arrived */
 	else if (lacpdu && ((port->sm_rx_state == AD_RX_EXPIRED) ||
 		 (port->sm_rx_state == AD_RX_DEFAULTED) ||
 		 (port->sm_rx_state == AD_RX_CURRENT))) {
+		if (port->sm_rx_state != AD_RX_CURRENT)
+			port->sm_vars |= AD_MONITOR_CHURNED;
 		port->sm_rx_timer_counter = 0;
 		port->sm_rx_state = AD_RX_CURRENT;
 	} else {
@@ -1100,9 +1104,11 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
 			 */
 			port->partner_oper.port_state &= ~AD_STATE_SYNCHRONIZATION;
 			port->sm_vars &= ~AD_PORT_MATCHED;
+			port->partner_oper.port_state |= AD_STATE_LACP_TIMEOUT;
 			port->partner_oper.port_state |= AD_STATE_LACP_ACTIVITY;
 			port->sm_rx_timer_counter = __ad_timer_to_ticks(AD_CURRENT_WHILE_TIMER, (u16)(AD_SHORT_TIMEOUT));
 			port->actor_oper_port_state |= AD_STATE_EXPIRED;
+			port->sm_vars |= AD_MONITOR_CHURNED;
 			break;
 		case AD_RX_DEFAULTED:
 			__update_default_selected(port);
@@ -1131,6 +1137,44 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
 	}
 }
 
+/* ad_churn_machine - handle port churn's state machine
+ * @port: the port we're looking at
+ *
+ */
+static void ad_churn_machine(struct port *port)
+{
+	if (port->sm_vars & AD_MONITOR_CHURNED) {
+		port->sm_vars &= ~AD_MONITOR_CHURNED;
+		port->sm_churn_actor_state = AD_CHURN_MONITOR;
+		port->sm_churn_partner_state = AD_CHURN_MONITOR;
+		port->sm_churn_actor_timer_counter =
+			__ad_timer_to_ticks(AD_ACTOR_CHURN_TIMER, 0);
+		 port->sm_churn_partner_timer_counter =
+			 __ad_timer_to_ticks(AD_PARTNER_CHURN_TIMER, 0);
+		return;
+	}
+	if (port->sm_churn_actor_timer_counter &&
+		!(--port->sm_churn_actor_timer_counter) &&
+		(port->sm_churn_actor_state == AD_CHURN_MONITOR)) {
+		if (port->actor_oper_port_state & AD_STATE_SYNCHRONIZATION) {
+			port->sm_churn_actor_state = AD_NO_CHURN;
+		} else {
+			port->churn_actor_count++;
+			port->sm_churn_actor_state = AD_CHURN;
+		}
+	}
+	if (port->sm_churn_partner_timer_counter &&
+		!(--port->sm_churn_partner_timer_counter) &&
+		(port->sm_churn_partner_state == AD_CHURN_MONITOR)) {
+		if (port->partner_oper.port_state & AD_STATE_SYNCHRONIZATION) {
+			port->sm_churn_partner_state = AD_NO_CHURN;
+		} else {
+			port->churn_partner_count++;
+			port->sm_churn_partner_state = AD_CHURN;
+		}
+	}
+}
+
 /**
  * ad_tx_machine - handle a port's tx state machine
  * @port: the port we're looking at
@@ -1745,6 +1789,13 @@ static void ad_initialize_port(struct port *port, int lacp_fast)
 		port->next_port_in_aggregator = NULL;
 		port->transaction_id = 0;
 
+		port->sm_churn_actor_timer_counter = 0;
+		port->sm_churn_actor_state = 0;
+		port->churn_actor_count = 0;
+		port->sm_churn_partner_timer_counter = 0;
+		port->sm_churn_partner_state = 0;
+		port->churn_partner_count = 0;
+
 		memcpy(&port->lacpdu, &lacpdu, sizeof(lacpdu));
 	}
 }
@@ -2164,6 +2215,7 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
 		ad_port_selection_logic(port, &update_slave_arr);
 		ad_mux_machine(port, &update_slave_arr);
 		ad_tx_machine(port);
+		ad_churn_machine(port);
 
 		/* turn off the BEGIN bit, since we already handled it */
 		if (port->sm_vars & AD_PORT_BEGIN)
diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c
index 976f5ad2a0f2..83095a0b4b90 100644
--- a/drivers/net/bonding/bond_procfs.c
+++ b/drivers/net/bonding/bond_procfs.c
@@ -178,13 +178,45 @@ static void bond_info_show_slave(struct seq_file *seq,
 	seq_printf(seq, "Permanent HW addr: %pM\n", slave->perm_hwaddr);
 
 	if (BOND_MODE(bond) == BOND_MODE_8023AD) {
-		const struct aggregator *agg
-			= SLAVE_AD_INFO(slave)->port.aggregator;
+		const struct port *port = &SLAVE_AD_INFO(slave)->port;
+		const struct aggregator *agg = port->aggregator;
 
-		if (agg)
+		if (agg) {
 			seq_printf(seq, "Aggregator ID: %d\n",
 				   agg->aggregator_identifier);
-		else
+			seq_printf(seq, "Actor Churn State: %s\n",
+				   bond_3ad_churn_desc(port->sm_churn_actor_state));
+			seq_printf(seq, "Partner Churn State: %s\n",
+				   bond_3ad_churn_desc(port->sm_churn_partner_state));
+			seq_printf(seq, "Actor Churned Count: %d\n",
+				   port->churn_actor_count);
+			seq_printf(seq, "Partner Churned Count: %d\n",
+				   port->churn_partner_count);
+
+			seq_puts(seq, "details actor lacp pdu:\n");
+			seq_printf(seq, "    system priority: %d\n",
+				   port->actor_system_priority);
+			seq_printf(seq, "    port key: %d\n",
+				   port->actor_oper_port_key);
+			seq_printf(seq, "    port priority: %d\n",
+				   port->actor_port_priority);
+			seq_printf(seq, "    port number: %d\n",
+				   port->actor_port_number);
+			seq_printf(seq, "    port state: %d\n",
+				   port->actor_oper_port_state);
+
+			seq_puts(seq, "details partner lacp pdu:\n");
+			seq_printf(seq, "    system priority: %d\n",
+				   port->partner_oper.system_priority);
+			seq_printf(seq, "    oper key: %d\n",
+				   port->partner_oper.key);
+			seq_printf(seq, "    port priority: %d\n",
+				   port->partner_oper.port_priority);
+			seq_printf(seq, "    port number: %d\n",
+				   port->partner_oper.port_number);
+			seq_printf(seq, "    port state: %d\n",
+				   port->partner_oper.port_state);
+		} else
 			seq_puts(seq, "Aggregator ID: N/A\n");
 	}
 	seq_printf(seq, "Slave queue ID: %d\n", slave->queue_id);
diff --git a/include/net/bond_3ad.h b/include/net/bond_3ad.h
index 6c455c646d61..170f8926ff66 100644
--- a/include/net/bond_3ad.h
+++ b/include/net/bond_3ad.h
@@ -82,6 +82,13 @@ typedef enum {
 	AD_TRANSMIT		/* tx Machine */
 } tx_states_t;
 
+/* churn machine states(43.4.17 in the 802.3ad standard) */
+typedef enum {
+	 AD_CHURN_MONITOR, /* monitoring for churn */
+	 AD_CHURN,         /* churn detected (error) */
+	 AD_NO_CHURN       /* no churn (no error) */
+} churn_state_t;
+
 /* rx indication types */
 typedef enum {
 	AD_TYPE_LACPDU = 1,	/* type lacpdu */
@@ -229,6 +236,12 @@ typedef struct port {
 	u16 sm_mux_timer_counter;	/* state machine mux timer counter */
 	tx_states_t sm_tx_state;	/* state machine tx state */
 	u16 sm_tx_timer_counter;	/* state machine tx timer counter(allways on - enter to transmit state 3 time per second) */
+	u16 sm_churn_actor_timer_counter;
+	u16 sm_churn_partner_timer_counter;
+	u32 churn_actor_count;
+	u32 churn_partner_count;
+	churn_state_t sm_churn_actor_state;
+	churn_state_t sm_churn_partner_state;
 	struct slave *slave;		/* pointer to the bond slave that this port belongs to */
 	struct aggregator *aggregator;	/* pointer to an aggregator that this port related to */
 	struct port *next_port_in_aggregator;	/* Next port on the linked list of the parent aggregator */
@@ -262,6 +275,22 @@ struct ad_slave_info {
 	u16 id;
 };
 
+static inline const char *bond_3ad_churn_desc(churn_state_t state)
+{
+	static const char *const churn_description[] =
+		{ "monitoring",
+		  "churned",
+		  "none",
+		  "unknown"
+		};
+	int max_size = sizeof(churn_description) / sizeof(churn_description[0]);
+
+	if (state >= max_size)
+		state = max_size - 1;
+
+	return churn_description[state];
+}
+
 /* ========== AD Exported functions to the main bonding code ========== */
 void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution);
 void bond_3ad_bind_slave(struct slave *slave);
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related

* [PATCH next 2/6] bonding: implement bond_poll_controller()
From: Mahesh Bandewar @ 2015-02-07  0:51 UTC (permalink / raw)
  To: Jay Vosburgh, Andy Gospodarek, Veaceslav Falico,
	Nikolay Aleksandrov, David Miller
  Cc: Mahesh Bandewar, netdev, Eric Dumazet

This patches implements the poll_controller support for all
bonding driver. If the slaves have poll_controller net_op defined,
this implementation calls them. This is mode agnostic implementation
and iterates through all slaves (based on mode) and calls respective
handler.

Signed-off-by: Mahesh Bandewar <maheshb@google.com>
---
 drivers/net/bonding/bond_3ad.c  | 24 +++++++++++++++++++++
 drivers/net/bonding/bond_main.c | 47 +++++++++++++++++++++++++++++++++++++++++
 include/net/bond_3ad.h          |  1 +
 3 files changed, 72 insertions(+)

diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 9b436696b95e..14f2ebe786c5 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2477,6 +2477,30 @@ int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info)
 	return ret;
 }
 
+#define BOND_3AD_PORT_OPERATIONAL \
+		(AD_STATE_DISTRIBUTING | AD_STATE_COLLECTING | \
+		 AD_STATE_SYNCHRONIZATION | AD_STATE_AGGREGATION)
+
+static int bond_3ad_port_operational(struct slave *slave)
+{
+	port_t *port = &SLAVE_AD_INFO(slave)->port;
+
+	return bond_slave_can_tx(slave) &&
+	       (port->actor_oper_port_state & port->partner_oper.port_state &
+		BOND_3AD_PORT_OPERATIONAL) == BOND_3AD_PORT_OPERATIONAL;
+}
+
+/* bond_3ad_port_is_active - check if a slave port is active or not. A port
+ * is active when it can forward traffic.
+ *
+ * @slave: slave port to check state for.
+ * Returns: 0 if not active else is active.
+ */
+int bond_3ad_port_is_active(struct slave *slave)
+{
+	return bond_3ad_port_operational(slave);
+}
+
 int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond,
 			 struct slave *slave)
 {
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index c9e519cb9214..a50ec87486f3 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -928,6 +928,53 @@ static inline void slave_disable_netpoll(struct slave *slave)
 
 static void bond_poll_controller(struct net_device *bond_dev)
 {
+	struct bonding *bond = netdev_priv(bond_dev);
+	struct slave *slave = NULL;
+	struct list_head *iter;
+	struct ad_info ad_info;
+	struct aggregator *agg;
+	const struct net_device_ops *ops;
+	bool call_slave_netpoll;
+
+	if (BOND_MODE(bond) == BOND_MODE_8023AD)
+		if (bond_3ad_get_active_agg_info(bond, &ad_info))
+			return;
+
+	bond_for_each_slave(bond, slave, iter) {
+		call_slave_netpoll = false;
+		switch (BOND_MODE(bond)) {
+		case BOND_MODE_8023AD:
+			agg = SLAVE_AD_INFO(slave)->port.aggregator;
+			if (!bond_slave_is_up(slave))
+				break;
+			if (agg && agg->aggregator_identifier !=
+				ad_info.aggregator_id)
+				break;
+			if (!bond_3ad_port_is_active(slave) &&
+			    ad_info.ports != 1)
+				break;
+
+			call_slave_netpoll = true;
+			break;
+		default:
+			if (bond_slave_is_up(slave))
+				call_slave_netpoll = true;
+			break;
+		}
+
+		if (call_slave_netpoll) {
+			ops = slave->dev->netdev_ops;
+			if (ops->ndo_poll_controller) {
+				struct netpoll_info *ni =
+					rcu_dereference_bh(slave->dev->npinfo);
+
+				if (down_trylock(&ni->dev_lock))
+					continue;
+				ops->ndo_poll_controller(slave->dev);
+				up(&ni->dev_lock);
+			}
+		}
+	}
 }
 
 static void bond_netpoll_cleanup(struct net_device *bond_dev)
diff --git a/include/net/bond_3ad.h b/include/net/bond_3ad.h
index f04cdbb7848e..6c455c646d61 100644
--- a/include/net/bond_3ad.h
+++ b/include/net/bond_3ad.h
@@ -278,5 +278,6 @@ int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond,
 			 struct slave *slave);
 int bond_3ad_set_carrier(struct bonding *bond);
 void bond_3ad_update_lacp_rate(struct bonding *bond);
+int bond_3ad_port_is_active(struct slave *slave);
 #endif /* _NET_BOND_3AD_H */
 
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related

* Re: panic on boot with latest net-next
From: Josh Hunt @ 2015-02-06 23:42 UTC (permalink / raw)
  To: Thomas Graf; +Cc: herbert, netdev
In-Reply-To: <54D53C11.1000208@akamai.com>

On 02/06/2015 04:11 PM, Josh Hunt wrote:
> On 02/06/2015 04:10 PM, Thomas Graf wrote:
>> On 02/06/15 at 03:02pm, Josh Hunt wrote:
>>> I'm hitting the following crash on boot with the latest net-next
>>> (2ca292d968ef20cb04f31192d1f626bd8d782960):
>>
>> Thanks for the report.
>>
>> This should be fixed by the patches posted in the thread:
>> [PATCH 0/6 v2 net-next] rhashtable fixes
>
> Thanks. I will apply those and see if it resolves my issue.

Applying those fixed my problem. I also just pulled the latest net-next 
with this series applied and that works as well.

Thanks
Josh

^ permalink raw reply

* Re: [PATCH net-next] rhashtable: Fix remove logic to avoid cross references between buckets
From: David Miller @ 2015-02-06 23:20 UTC (permalink / raw)
  To: tgraf; +Cc: ying.xue, netdev, herbert
In-Reply-To: <20150206160843.GA31371@casper.infradead.org>

From: Thomas Graf <tgraf@suug.ch>
Date: Fri, 6 Feb 2015 16:08:43 +0000

> The remove logic properly searched the remaining chain for a matching
> entry with an identical hash but it did this while searching from both
> the old and new table. Instead in order to not leave stale references
> behind we need to:
> 
>  1. When growing and searching from the new table:
>     Search remaining chain for entry with same hash to avoid having
>     the new table directly point to a entry with a different hash.
> 
>  2. When shrinking and searching from the old table:
>     Check if the element after the removed would create a cross
>     reference and avoid it if so.
> 
> These bugs were present from the beginning in nft_hash.
> 
> Also, both insert functions calculated the hash based on the mask of
> the new table. This worked while growing. Wwhile shrinking, the mask
> of the inew table is smaller than the mask of the old table. This lead
> to a bit not being taken into account when selecting the bucket lock
> and thus caused the wrong bucket to be locked eventually.
> 
> Fixes: 7e1e77636e36 ("lib: Resizable, Scalable, Concurrent Hash Table")
> Fixes: 97defe1ecf86 ("rhashtable: Per bucket locks & deferred expansion/shrinking")
> Reported-by: Ying Xue <ying.xue@windriver.com>
> Signed-off-by: Thomas Graf <tgraf@suug.ch>

Applied.

^ permalink raw reply

* Re: [PATCH 0/6 v2 net-next] rhashtable fixes
From: David Miller @ 2015-02-06 23:20 UTC (permalink / raw)
  To: tgraf; +Cc: netdev, herbert, ying.xue
In-Reply-To: <cover.1423097592.git.tgraf@suug.ch>

From: Thomas Graf <tgraf@suug.ch>
Date: Thu,  5 Feb 2015 02:03:30 +0100

> This series fixes all remaining known issues with rhashtable that
> have been reported. In particular the race condition reported by
> Ying Xue.
> 
> ---
> Dave/Herbert: I'm posting this now as it fixes real issues. I'm
> fine with taking Herbert's rehash patches instead if they resolve
> all the reported issues as well.
> 
> v2:
>  - Rebased on top of Herbert Xu's iterator code
>  - Fixed last remaining race that remained. Special thanks
>    to Daniel Borkmann for assistance while debugging.

Since this supposedly fixes crashes on bootup for some people
I'm applying this series now.

Herbert, I apologize in advance if this makes your work more
difficult but I asked you yesterday what you wanted me to
do with this series...

Thanks.

^ permalink raw reply

* Re: [PATCH] cipso: don't use IPCB() to locate the CIPSO IP option
From: Casey Schaufler @ 2015-02-06 22:51 UTC (permalink / raw)
  To: Paul Moore, davem; +Cc: linux-security-module, selinux, netdev, Casey Schaufler
In-Reply-To: <79075962.e3G0NVBHuh@sifl>

On 2/6/2015 12:03 PM, Paul Moore wrote:
> On Friday, February 06, 2015 02:57:28 PM Paul Moore wrote:
>> Using the IPCB() macro to get the IPv4 options is convenient, but
>> unfortunately NetLabel often needs to examine the CIPSO option outside
>> of the scope of the IP layer in the stack.  While historically IPCB()
>> worked above the IP layer, due to the inclusion of the inet_skb_param
>> struct at the head of the {tcp,udp}_skb_cb structs, recent commit
>> 971f10ec ("tcp: better TCP_SKB_CB layout to reduce cache line misses")
>> reordered the tcp_skb_cb struct and invalidated this IPCB() trick.
>>
>> This patch fixes the problem by creating a new function,
>> cipso_v4_optptr(), which locates the CIPSO option inside the IP header
>> without calling IPCB().  Unfortunately, this isn't as fast as a simple
>> lookup so some additional tweaks were made to limit the use of this
>> new function.
>>
>> Cc: <stable@vger.kernel.org> # 3.18
>> Reported-by: Casey Schaufler <casey@schaufler-ca.com>
>> Signed-off-by: Paul Moore <pmoore@redhat.com>

Tested-by: Casey Schaufler <casey@schaufler-ca.com>
 

> DaveM, I'd prefer this go upstream via the SELinux/security tree so we don't 
> have to worry about syncing up with the netdev tree to get this fix.  Any 
> objections on your part (this patch only touches NetLabel/CIPSO)?
>


^ permalink raw reply

* Re: [PATCH] cipso: don't use IPCB() to locate the CIPSO IP option
From: David Miller @ 2015-02-06 22:27 UTC (permalink / raw)
  To: pmoore; +Cc: linux-security-module, selinux, casey, netdev
In-Reply-To: <79075962.e3G0NVBHuh@sifl>

From: Paul Moore <pmoore@redhat.com>
Date: Fri, 06 Feb 2015 15:03:05 -0500

> On Friday, February 06, 2015 02:57:28 PM Paul Moore wrote:
>> Using the IPCB() macro to get the IPv4 options is convenient, but
>> unfortunately NetLabel often needs to examine the CIPSO option outside
>> of the scope of the IP layer in the stack.  While historically IPCB()
>> worked above the IP layer, due to the inclusion of the inet_skb_param
>> struct at the head of the {tcp,udp}_skb_cb structs, recent commit
>> 971f10ec ("tcp: better TCP_SKB_CB layout to reduce cache line misses")
>> reordered the tcp_skb_cb struct and invalidated this IPCB() trick.
>> 
>> This patch fixes the problem by creating a new function,
>> cipso_v4_optptr(), which locates the CIPSO option inside the IP header
>> without calling IPCB().  Unfortunately, this isn't as fast as a simple
>> lookup so some additional tweaks were made to limit the use of this
>> new function.
>> 
>> Cc: <stable@vger.kernel.org> # 3.18
>> Reported-by: Casey Schaufler <casey@schaufler-ca.com>
>> Signed-off-by: Paul Moore <pmoore@redhat.com>
> 
> DaveM, I'd prefer this go upstream via the SELinux/security tree so we don't 
> have to worry about syncing up with the netdev tree to get this fix.  Any 
> objections on your part (this patch only touches NetLabel/CIPSO)?

No objections, please take it.

^ permalink raw reply

* Re: [PATCH] ath9k_htc: add adaptive usb receive flow control to repair soft lockup with monitor mode
From: Oleksij Rempel @ 2015-02-06 22:24 UTC (permalink / raw)
  To: yuweizheng, linux-kernel, ath9k-devel, linux-wireless, kvalo,
	ath9k-devel
  Cc: netdev, zhengyuwei
In-Reply-To: <1423219598-17982-1-git-send-email-yuweizheng@139.com>

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

formatting of this patch is still badly broken.
./scripts/checkpatch.pl ~/Downloads/patch.eml
....
ERROR: DOS line endings
#442: FILE: drivers/net/wireless/ath/ath9k/htc_drv_txrx.c:1170:
+^I^IAURFC_STAT_SET(aurfc_submit_delay, delay);^M$

total: 195 errors, 6 warnings, 1 checks, 310 lines checked


Am 06.02.2015 um 11:46 schrieb yuweizheng@139.com:
> From: Yuwei Zheng <yuweizheng@139.com>
> 
> In the environment with heavy wifi traffic, set the ar9271 into monitor mode, will
> trigger a deadloop panic.
>  
> The ath9k_hif_usb_rx_cb function excute on  the interrupt context, and ath9k_rx_tasklet excute
> on the soft irq context. In other words, the ath9k_hif_usb_rx_cb have more chance to excute than
> ath9k_rx_tasklet.  So in the worst condition,  the rx.rxbuf receive list is always full,
> and the do {}while(true) loop will not be break. The kernel get a soft lockup panic. 
>  
> [59011.007210] BUG: soft lockup - CPU#0 stuck for 23s!
> [kworker/0:0:30609]
> [59011.030560] BUG: scheduling while atomic: kworker/0:0/30609/0x40010100
> [59013.804486] BUG: scheduling while atomic: kworker/0:0/30609/0x40010100
> [59013.858522] Kernel panic - not syncing: softlockup: hung tasks
>  
> [59014.038891] Exception stack(0xdf4bbc38 to 0xdf4bbc80)
> [59014.046834] bc20:                                                       de57b950 60000113
> [59014.059579] bc40: 00000000 bb32bb32 60000113 de57b948 de57b500 dc7bb440 df4bbcd0 00000000
> [59014.072337] bc60: de57b950 60000113 df4bbcd0 df4bbc80 c04c259d c04c25a0 60000133 ffffffff
> [59014.085233] [<c04c28db>] (__irq_svc+0x3b/0x5c) from [<c04c25a0>] (_raw_spin_unlock_irqrestore+0xc/0x10)
> [59014.100437] [<c04c25a0>] (_raw_spin_unlock_irqrestore+0xc/0x10) from [<bf9c2089>] (ath9k_rx_tasklet+0x290/0x490 [ath9k_htc])
> [59014.118267] [<bf9c2089>] (ath9k_rx_tasklet+0x290/0x490 [ath9k_htc]) from [<c0036d23>] (tasklet_action+0x3b/0x98)
> [59014.134132] [<c0036d23>] (tasklet_action+0x3b/0x98) from [<c0036709>] (__do_softirq+0x99/0x16c)
> [59014.147784] [<c0036709>] (__do_softirq+0x99/0x16c) from [<c00369f7>] (irq_exit+0x5b/0x5c)
> [59014.160653] [<c00369f7>] (irq_exit+0x5b/0x5c) from [<c000cfc3>] (handle_IRQ+0x37/0x78)
> [59014.173124] [<c000cfc3>] (handle_IRQ+0x37/0x78) from [<c00085df>] (omap3_intc_handle_irq+0x5f/0x68)
> [59014.187225] [<c00085df>] (omap3_intc_handle_irq+0x5f/0x68) from [<c04c28db>](__irq_svc+0x3b/0x5c)
>  
> This bug can be see with low performance board, such as uniprocessor beagle bone board. 
>  
> Signed-off-by: Yuwei Zheng <yuweizheng@139.com>
> 
> ---
>  drivers/net/wireless/ath/ath9k/hif_usb.c       | 74 +++++++++++++++++++++++---
>  drivers/net/wireless/ath/ath9k/hif_usb.h       |  9 ++++
>  drivers/net/wireless/ath/ath9k/htc.h           | 19 +++++++
>  drivers/net/wireless/ath/ath9k/htc_drv_debug.c | 53 ++++++++++++++++++
>  drivers/net/wireless/ath/ath9k/htc_drv_txrx.c  | 44 +++++++++++++++
>  5 files changed, 192 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
> index 8e7153b..90ee568 100644
> --- a/drivers/net/wireless/ath/ath9k/hif_usb.c
> +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
> @@ -640,6 +640,7 @@ static void ath9k_hif_usb_rx_cb(struct urb *urb)
>  	struct hif_device_usb *hif_dev =
>  		usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
>  	int ret;
> +	int delay;
>  
>  	if (!skb)
>  		return;
> @@ -658,7 +659,6 @@ static void ath9k_hif_usb_rx_cb(struct urb *urb)
>  	default:
>  		goto resubmit;
>  	}
> -
>  	if (likely(urb->actual_length != 0)) {
>  		skb_put(skb, urb->actual_length);
>  		ath9k_hif_usb_rx_stream(hif_dev, skb);
> @@ -667,12 +667,22 @@ static void ath9k_hif_usb_rx_cb(struct urb *urb)
>  resubmit:
>  	skb_reset_tail_pointer(skb);
>  	skb_trim(skb, 0);
> -
> -	usb_anchor_urb(urb, &hif_dev->rx_submitted);
> -	ret = usb_submit_urb(urb, GFP_ATOMIC);
> -	if (ret) {
> -		usb_unanchor_urb(urb);
> -		goto free;
> +	spin_lock(&hif_dev->aurfc_lock);
> +	if (atomic_read(&hif_dev->aurfc_submit_delay) > 0 &&
> +	    hif_dev->aurfc_active == 1) {
> +		usb_anchor_urb(urb, &hif_dev->rx_delayed_submitted);
> +		delay = atomic_read(&hif_dev->aurfc_submit_delay);
> +		schedule_delayed_work(&hif_dev->aurfc_delayed_work,
> +				      msecs_to_jiffies(delay));
> +		spin_unlock(&hif_dev->aurfc_lock);
> +	} else {
> +		spin_unlock(&hif_dev->aurfc_lock);
> +		usb_anchor_urb(urb, &hif_dev->rx_submitted);
> +		ret = usb_submit_urb(urb, GFP_ATOMIC);
> +		if (ret) {
> +			usb_unanchor_urb(urb);
> +			goto free;
> +		}
>  	}
>  
>  	return;
> @@ -818,9 +828,50 @@ err:
>  	return -ENOMEM;
>  }
>  
> +static void aurfc_submit_handler(struct work_struct *work)
> +{
> +	struct hif_device_usb *hif_dev =
> +		container_of(work,
> +			     struct hif_device_usb,
> +			     aurfc_delayed_work.work);
> +
> +	struct urb *urb = NULL;
> +	struct sk_buff *skb = NULL;
> +	int ret;
> +	int loop_times = 0;
> +
> +	while (true) {
> +		loop_times++;
> +		if (loop_times > MAX_RX_URB_NUM)
> +			atomic_add(AURFC_STEP,
> +				   &hif_dev->aurfc_submit_delay);
> +
> +		urb = usb_get_from_anchor(
> +				&hif_dev->rx_delayed_submitted);
> +		if (urb) {
> +			skb = (struct sk_buff *)urb->context;
> +			ret = usb_submit_urb(urb, GFP_KERNEL);
> +			if (ret != 0) {
> +				usb_unanchor_urb(urb);
> +				dev_kfree_skb_any(skb);
> +				urb->context = NULL;
> +			}
> +		} else {
> +			break;
> +		}
> +	}
> +}
> +
>  static void ath9k_hif_usb_dealloc_rx_urbs(struct hif_device_usb *hif_dev)
>  {
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&hif_dev->aurfc_lock, flags);
> +	hif_dev->aurfc_active = 0;
> +	mod_delayed_work(system_wq, &hif_dev->aurfc_delayed_work, 0);
> +	spin_unlock_irqrestore(&hif_dev->aurfc_lock, flags);
>  	usb_kill_anchored_urbs(&hif_dev->rx_submitted);
> +	usb_kill_anchored_urbs(&hif_dev->rx_delayed_submitted);
>  }
>  
>  static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
> @@ -830,8 +881,17 @@ static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
>  	int i, ret;
>  
>  	init_usb_anchor(&hif_dev->rx_submitted);
> +	init_usb_anchor(&hif_dev->rx_delayed_submitted);
> +
>  	spin_lock_init(&hif_dev->rx_lock);
>  
> +	/* add for adaptive usb receive control*/
> +	atomic_set(&hif_dev->aurfc_submit_delay, 0);
> +	INIT_DELAYED_WORK(&hif_dev->aurfc_delayed_work,
> +			  aurfc_submit_handler);
> +	spin_lock_init(&hif_dev->aurfc_lock);
> +	hif_dev->aurfc_active = 1;
> +
>  	for (i = 0; i < MAX_RX_URB_NUM; i++) {
>  
>  		/* Allocate URB */
> diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h
> index 51496e7..2050a74 100644
> --- a/drivers/net/wireless/ath/ath9k/hif_usb.h
> +++ b/drivers/net/wireless/ath/ath9k/hif_usb.h
> @@ -41,6 +41,7 @@
>  #define MAX_RX_URB_NUM  8
>  #define MAX_RX_BUF_SIZE 16384
>  #define MAX_PKT_NUM_IN_TRANSFER 10
> +#define AURFC_STEP 10  /* ms */
>  
>  #define MAX_REG_OUT_URB_NUM  1
>  #define MAX_REG_IN_URB_NUM   64
> @@ -98,9 +99,17 @@ struct hif_device_usb {
>  	struct hif_usb_tx tx;
>  	struct usb_anchor regout_submitted;
>  	struct usb_anchor rx_submitted;
> +	struct usb_anchor rx_delayed_submitted;
>  	struct usb_anchor reg_in_submitted;
>  	struct usb_anchor mgmt_submitted;
>  	struct sk_buff *remain_skb;
> +
> +	/* adaptive usb receive flow control */
> +	struct delayed_work aurfc_delayed_work;
> +	spinlock_t aurfc_lock; /* to protect work */
> +	atomic_t  aurfc_submit_delay; /* ms */
> +	int aurfc_active;
> +
>  	const char *fw_name;
>  	int rx_remain_len;
>  	int rx_pkt_len;
> diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
> index 9dde265..1586bd2 100644
> --- a/drivers/net/wireless/ath/ath9k/htc.h
> +++ b/drivers/net/wireless/ath/ath9k/htc.h
> @@ -331,6 +331,13 @@ static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb)
>  
>  #define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++)
>  
> +#define AURFC_STAT_INC(c) \
> +	(hif_dev->htc_handle->drv_priv->debug.aurfc_stats.c++)
> +#define AURFC_STAT_ADD(c, a) \
> +	(hif_dev->htc_handle->drv_priv->debug.aurfc_stats.c += a)
> +#define AURFC_STAT_SET(c, a) \
> +	(hif_dev->htc_handle->drv_priv->debug.aurfc_stats.c = a)
> +
>  void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,
>  			   struct ath_rx_status *rs);
>  
> @@ -352,11 +359,20 @@ struct ath_skbrx_stats {
>  	u32 skb_dropped;
>  };
>  
> +struct ath_aurfc_stats {
> +	u32 aurfc_highwater;
> +	u32 aurfc_lowwater;
> +	u32 aurfc_wm_triggered;
> +	u32 aurfc_submit_delay;
> +	u32 aurfc_called;
> +};
> +
>  struct ath9k_debug {
>  	struct dentry *debugfs_phy;
>  	struct ath_tx_stats tx_stats;
>  	struct ath_rx_stats rx_stats;
>  	struct ath_skbrx_stats skbrx_stats;
> +	struct ath_aurfc_stats aurfc_stats;
>  };
>  
>  void ath9k_htc_get_et_strings(struct ieee80211_hw *hw,
> @@ -377,6 +393,9 @@ void ath9k_htc_get_et_stats(struct ieee80211_hw *hw,
>  
>  #define TX_QSTAT_INC(c) do { } while (0)
>  
> +#define AURFC_STAT_INC(c) do {} while (0)
> +#define AURFC_STAT_ADD(c, a) do {} while (0)
> +#define AURFC_STAT_SET(c, a) do {} while (0)
>  static inline void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,
>  					 struct ath_rx_status *rs)
>  {
> diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
> index 8cef1ed..a6be9be 100644
> --- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
> +++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
> @@ -286,6 +286,54 @@ static const struct file_operations fops_skb_rx = {
>  	.llseek = default_llseek,
>  };
>  
> +static ssize_t read_file_aurfc(struct file *file,
> +			       char __user *user_buf,
> +			       size_t count, loff_t *ppos)
> +{
> +	struct ath9k_htc_priv *priv = file->private_data;
> +	char *buf;
> +	unsigned int len = 0, size = 1500;
> +	ssize_t retval = 0;
> +
> +	buf = kzalloc(size, GFP_KERNEL);
> +	if (!buf)
> +		return -ENOMEM;
> +
> +	len += scnprintf(buf + len, size - len,
> +			"%20s : %10u\n", "High watermark",
> +			priv->debug.aurfc_stats.aurfc_highwater);
> +	len += scnprintf(buf + len, size - len,
> +			"%20s : %10u\n", "Low watermark",
> +			priv->debug.aurfc_stats.aurfc_lowwater);
> +
> +	len += scnprintf(buf + len, size - len,
> +			"%20s : %10u\n", "WM triggered",
> +			priv->debug.aurfc_stats.aurfc_wm_triggered);
> +
> +	len += scnprintf(buf + len, size - len,
> +			"%20s : %10u\n", "Handler called",
> +			priv->debug.aurfc_stats.aurfc_called);
> +
> +	len += scnprintf(buf + len, size - len,
> +			"%20s : %10u\n", "Submit delay",
> +			priv->debug.aurfc_stats.aurfc_submit_delay);
> +	if (len > size)
> +		len = size;
> +
> +	retval = simple_read_from_buffer(user_buf, count,
> +					 ppos, buf, len);
> +	kfree(buf);
> +
> +	return retval;
> +}
> +
> +static const struct file_operations fops_aurfc = {
> +	.read = read_file_aurfc,
> +	.open = simple_open,
> +	.owner = THIS_MODULE,
> +	.llseek = default_llseek,
> +};
> +
>  static ssize_t read_file_slot(struct file *file, char __user *user_buf,
>  			      size_t count, loff_t *ppos)
>  {
> @@ -518,7 +566,12 @@ int ath9k_htc_init_debug(struct ath_hw *ah)
>  	debugfs_create_file("skb_rx", S_IRUSR, priv->debug.debugfs_phy,
>  			    priv, &fops_skb_rx);
>  
> +	debugfs_create_file("aurfc_stats", S_IRUSR,
> +			    priv->debug.debugfs_phy,
> +			    priv, &fops_aurfc);
> +
>  	ath9k_cmn_debug_recv(priv->debug.debugfs_phy, &priv->debug.rx_stats);
> +
>  	ath9k_cmn_debug_phy_err(priv->debug.debugfs_phy, &priv->debug.rx_stats);
>  
>  	debugfs_create_file("slot", S_IRUSR, priv->debug.debugfs_phy,
> diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
> index a0f58e2..939d008 100644
> --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
> +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
> @@ -1061,7 +1061,28 @@ void ath9k_rx_tasklet(unsigned long data)
>  	unsigned long flags;
>  	struct ieee80211_hdr *hdr;
>  
> +	/* add for adaptive usb receive flow control*/
> +	int looptimes = 0;
> +	int highwatermark = ATH9K_HTC_RXBUF*3/4;
> +	int lowwatermark = ATH9K_HTC_RXBUF/32;
> +	unsigned int delay = 0;
> +
> +	struct htc_target *htc = priv->htc;
> +	struct hif_device_usb *hif_dev = htc->hif_dev;
> +
> +	AURFC_STAT_SET(aurfc_highwater, highwatermark);
> +	AURFC_STAT_SET(aurfc_lowwater, lowwatermark);
> +
>  	do {
> +		looptimes++;
> +		if (looptimes > highwatermark) {
> +			delay = looptimes*AURFC_STEP;
> +			atomic_set(&hif_dev->aurfc_submit_delay,
> +				   delay);
> +			AURFC_STAT_INC(aurfc_wm_triggered);
> +			AURFC_STAT_SET(aurfc_submit_delay, delay);
> +		}
> +
>  		spin_lock_irqsave(&priv->rx.rxbuflock, flags);
>  		list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) {
>  			if (tmp_buf->in_process) {
> @@ -1072,6 +1093,22 @@ void ath9k_rx_tasklet(unsigned long data)
>  
>  		if (rxbuf == NULL) {
>  			spin_unlock_irqrestore(&priv->rx.rxbuflock, flags);
> +			spin_lock_irqsave(&hif_dev->aurfc_lock,
> +					  flags);
> +			if (atomic_read(
> +				&hif_dev->aurfc_submit_delay) > 0 &&
> +			    hif_dev->aurfc_active > 0)
> +				mod_delayed_work(system_wq,
> +					&hif_dev->aurfc_delayed_work,
> +						 0);
> +			spin_unlock_irqrestore(&hif_dev->aurfc_lock,
> +					       flags);
> +			if (looptimes < lowwatermark) {
> +				atomic_set(&hif_dev->aurfc_submit_delay
> +					   , 0);
> +				AURFC_STAT_SET(aurfc_submit_delay,
> +					       0);
> +			}
>  			break;
>  		}
>  
> @@ -1114,6 +1151,10 @@ void ath9k_htc_rxep(void *drv_priv, struct sk_buff *skb,
>  	struct ath_common *common = ath9k_hw_common(ah);
>  	struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL;
>  
> +	struct htc_target *htc = priv->htc;
> +	struct hif_device_usb *hif_dev = htc->hif_dev;
> +	int delay = ATH9K_HTC_RXBUF * AURFC_STEP;
> +
>  	spin_lock(&priv->rx.rxbuflock);
>  	list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) {
>  		if (!tmp_buf->in_process) {
> @@ -1124,6 +1165,9 @@ void ath9k_htc_rxep(void *drv_priv, struct sk_buff *skb,
>  	spin_unlock(&priv->rx.rxbuflock);
>  
>  	if (rxbuf == NULL) {
> +		atomic_set(&hif_dev->aurfc_submit_delay, delay);
> +		AURFC_STAT_INC(aurfc_wm_triggered);
> +		AURFC_STAT_SET(aurfc_submit_delay, delay);
>  		ath_dbg(common, ANY, "No free RX buffer\n");
>  		goto err;
>  	}
> 


-- 
Regards,
Oleksij


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

^ permalink raw reply

* Re: [PATCH net-next] net: rfs: add hash collision detection
From: Tom Herbert @ 2015-02-06 22:21 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, netdev, Ying Cai, Willem de Bruijn
In-Reply-To: <1423256341.31870.160.camel@edumazet-glaptop2.roam.corp.google.com>

On Fri, Feb 6, 2015 at 12:59 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> From: Eric Dumazet <edumazet@google.com>
>
> Receive Flow Steering is a nice solution but suffers from
> hash collisions when a mix of connected and unconnected traffic
> is received on the host, when flow hash table is populated.
>
> Also, clearing flow in inet_release() makes RFS not very good
> for short lived flows, as many packets can follow close().
> (FIN , ACK packets, ...)
>
> This patch extends the information stored into global hash table
> to not only include cpu number, but upper part of the hash value.
>
> I use a 32bit value, and dynamically split it in two parts.
>
> For host with less than 64 possible cpus, this gives 6 bits for the
> cpu number, and 26 (32-6) bits for the upper part of the hash.
>
> Since hash bucket selection use low order bits of the hash, we have
> a full hash match, if /proc/sys/net/core/rps_sock_flow_entries is big
> enough.
>
> If the hash found in flow table does not match, we fallback to RPS (if
> it is enabled for the rxqueue).
>
> This means that a packet for an non connected flow can avoid the
> IPI through a unrelated/victim CPU.
>
> This also means we no longer have to clear the table at socket
> close time, and this helps short lived flows performance.
>

Acked-by: Tom Herbert <therbert@google.com>

Eric, looks awesome! Can you share any performance numbers?

Thanks,
Tom

> Signed-off-by: Eric Dumazet <edumazet@google.com>
> ---
>  drivers/net/tun.c          |    5 ---
>  include/linux/netdevice.h  |   34 ++++++++++++------------
>  include/net/sock.h         |   24 -----------------
>  net/core/dev.c             |   48 +++++++++++++++++++----------------
>  net/core/sysctl_net_core.c |    2 -
>  net/ipv4/af_inet.c         |    2 -
>  6 files changed, 47 insertions(+), 68 deletions(-)
>
> diff --git a/drivers/net/tun.c b/drivers/net/tun.c
> index ad7d3d5f3ee5..857dca47bf80 100644
> --- a/drivers/net/tun.c
> +++ b/drivers/net/tun.c
> @@ -256,7 +256,6 @@ static void tun_flow_delete(struct tun_struct *tun, struct tun_flow_entry *e)
>  {
>         tun_debug(KERN_INFO, tun, "delete flow: hash %u index %u\n",
>                   e->rxhash, e->queue_index);
> -       sock_rps_reset_flow_hash(e->rps_rxhash);
>         hlist_del_rcu(&e->hash_link);
>         kfree_rcu(e, rcu);
>         --tun->flow_count;
> @@ -373,10 +372,8 @@ unlock:
>   */
>  static inline void tun_flow_save_rps_rxhash(struct tun_flow_entry *e, u32 hash)
>  {
> -       if (unlikely(e->rps_rxhash != hash)) {
> -               sock_rps_reset_flow_hash(e->rps_rxhash);
> +       if (unlikely(e->rps_rxhash != hash))
>                 e->rps_rxhash = hash;
> -       }
>  }
>
>  /* We try to identify a flow through its rxhash first. The reason that
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index ce784d5018e0..ab3b7cef4638 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -644,39 +644,39 @@ struct rps_dev_flow_table {
>  /*
>   * The rps_sock_flow_table contains mappings of flows to the last CPU
>   * on which they were processed by the application (set in recvmsg).
> + * Each entry is a 32bit value. Upper part is the high order bits
> + * of flow hash, lower part is cpu number.
> + * rps_cpu_mask is used to partition the space, depending on number of
> + * possible cpus : rps_cpu_mask = roundup_pow_of_two(nr_cpu_ids) - 1
> + * For example, if 64 cpus are possible, rps_cpu_mask = 0x3f,
> + * meaning we use 32-6=26 bits for the hash.
>   */
>  struct rps_sock_flow_table {
> -       unsigned int mask;
> -       u16 ents[0];
> +       u32     mask;
> +       u32     ents[0];
>  };
> -#define        RPS_SOCK_FLOW_TABLE_SIZE(_num) (sizeof(struct rps_sock_flow_table) + \
> -    ((_num) * sizeof(u16)))
> +#define        RPS_SOCK_FLOW_TABLE_SIZE(_num) (offsetof(struct rps_sock_flow_table, ents[_num]))
>
>  #define RPS_NO_CPU 0xffff
>
> +extern u32 rps_cpu_mask;
> +extern struct rps_sock_flow_table __rcu *rps_sock_flow_table;
> +
>  static inline void rps_record_sock_flow(struct rps_sock_flow_table *table,
>                                         u32 hash)
>  {
>         if (table && hash) {
> -               unsigned int cpu, index = hash & table->mask;
> +               unsigned int index = hash & table->mask;
> +               u32 val = hash & ~rps_cpu_mask;
>
>                 /* We only give a hint, preemption can change cpu under us */
> -               cpu = raw_smp_processor_id();
> +               val |= raw_smp_processor_id();
>
> -               if (table->ents[index] != cpu)
> -                       table->ents[index] = cpu;
> +               if (table->ents[index] != val)
> +                       table->ents[index] = val;
>         }
>  }
>
> -static inline void rps_reset_sock_flow(struct rps_sock_flow_table *table,
> -                                      u32 hash)
> -{
> -       if (table && hash)
> -               table->ents[hash & table->mask] = RPS_NO_CPU;
> -}
> -
> -extern struct rps_sock_flow_table __rcu *rps_sock_flow_table;
> -
>  #ifdef CONFIG_RFS_ACCEL
>  bool rps_may_expire_flow(struct net_device *dev, u16 rxq_index, u32 flow_id,
>                          u16 filter_id);
> diff --git a/include/net/sock.h b/include/net/sock.h
> index d28b8fededd6..e13824570b0f 100644
> --- a/include/net/sock.h
> +++ b/include/net/sock.h
> @@ -857,18 +857,6 @@ static inline void sock_rps_record_flow_hash(__u32 hash)
>  #endif
>  }
>
> -static inline void sock_rps_reset_flow_hash(__u32 hash)
> -{
> -#ifdef CONFIG_RPS
> -       struct rps_sock_flow_table *sock_flow_table;
> -
> -       rcu_read_lock();
> -       sock_flow_table = rcu_dereference(rps_sock_flow_table);
> -       rps_reset_sock_flow(sock_flow_table, hash);
> -       rcu_read_unlock();
> -#endif
> -}
> -
>  static inline void sock_rps_record_flow(const struct sock *sk)
>  {
>  #ifdef CONFIG_RPS
> @@ -876,28 +864,18 @@ static inline void sock_rps_record_flow(const struct sock *sk)
>  #endif
>  }
>
> -static inline void sock_rps_reset_flow(const struct sock *sk)
> -{
> -#ifdef CONFIG_RPS
> -       sock_rps_reset_flow_hash(sk->sk_rxhash);
> -#endif
> -}
> -
>  static inline void sock_rps_save_rxhash(struct sock *sk,
>                                         const struct sk_buff *skb)
>  {
>  #ifdef CONFIG_RPS
> -       if (unlikely(sk->sk_rxhash != skb->hash)) {
> -               sock_rps_reset_flow(sk);
> +       if (unlikely(sk->sk_rxhash != skb->hash))
>                 sk->sk_rxhash = skb->hash;
> -       }
>  #endif
>  }
>
>  static inline void sock_rps_reset_rxhash(struct sock *sk)
>  {
>  #ifdef CONFIG_RPS
> -       sock_rps_reset_flow(sk);
>         sk->sk_rxhash = 0;
>  #endif
>  }
> diff --git a/net/core/dev.c b/net/core/dev.c
> index a3a96ffc67f4..8be38675e1a8 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -3030,6 +3030,8 @@ static inline void ____napi_schedule(struct softnet_data *sd,
>  /* One global table that all flow-based protocols share. */
>  struct rps_sock_flow_table __rcu *rps_sock_flow_table __read_mostly;
>  EXPORT_SYMBOL(rps_sock_flow_table);
> +u32 rps_cpu_mask __read_mostly;
> +EXPORT_SYMBOL(rps_cpu_mask);
>
>  struct static_key rps_needed __read_mostly;
>
> @@ -3086,16 +3088,17 @@ set_rps_cpu(struct net_device *dev, struct sk_buff *skb,
>  static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb,
>                        struct rps_dev_flow **rflowp)
>  {
> -       struct netdev_rx_queue *rxqueue;
> -       struct rps_map *map;
> +       const struct rps_sock_flow_table *sock_flow_table;
> +       struct netdev_rx_queue *rxqueue = dev->_rx;
>         struct rps_dev_flow_table *flow_table;
> -       struct rps_sock_flow_table *sock_flow_table;
> +       struct rps_map *map;
>         int cpu = -1;
> -       u16 tcpu;
> +       u32 tcpu;
>         u32 hash;
>
>         if (skb_rx_queue_recorded(skb)) {
>                 u16 index = skb_get_rx_queue(skb);
> +
>                 if (unlikely(index >= dev->real_num_rx_queues)) {
>                         WARN_ONCE(dev->real_num_rx_queues > 1,
>                                   "%s received packet on queue %u, but number "
> @@ -3103,39 +3106,40 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb,
>                                   dev->name, index, dev->real_num_rx_queues);
>                         goto done;
>                 }
> -               rxqueue = dev->_rx + index;
> -       } else
> -               rxqueue = dev->_rx;
> +               rxqueue += index;
> +       }
>
> +       /* Avoid computing hash if RFS/RPS is not active for this rxqueue */
> +
> +       flow_table = rcu_dereference(rxqueue->rps_flow_table);
>         map = rcu_dereference(rxqueue->rps_map);
> -       if (map) {
> -               if (map->len == 1 &&
> -                   !rcu_access_pointer(rxqueue->rps_flow_table)) {
> -                       tcpu = map->cpus[0];
> -                       if (cpu_online(tcpu))
> -                               cpu = tcpu;
> -                       goto done;
> -               }
> -       } else if (!rcu_access_pointer(rxqueue->rps_flow_table)) {
> +       if (!flow_table && !map)
>                 goto done;
> -       }
>
>         skb_reset_network_header(skb);
>         hash = skb_get_hash(skb);
>         if (!hash)
>                 goto done;
>
> -       flow_table = rcu_dereference(rxqueue->rps_flow_table);
>         sock_flow_table = rcu_dereference(rps_sock_flow_table);
>         if (flow_table && sock_flow_table) {
> -               u16 next_cpu;
>                 struct rps_dev_flow *rflow;
> +               u32 next_cpu;
> +               u32 ident;
> +
> +               /* First check into global flow table if there is a match */
> +               ident = sock_flow_table->ents[hash & sock_flow_table->mask];
> +               if ((ident ^ hash) & ~rps_cpu_mask)
> +                       goto try_rps;
>
> +               next_cpu = ident & rps_cpu_mask;
> +
> +               /* OK, now we know there is a match,
> +                * we can look at the local (per receive queue) flow table
> +                */
>                 rflow = &flow_table->flows[hash & flow_table->mask];
>                 tcpu = rflow->cpu;
>
> -               next_cpu = sock_flow_table->ents[hash & sock_flow_table->mask];
> -
>                 /*
>                  * If the desired CPU (where last recvmsg was done) is
>                  * different from current CPU (one in the rx-queue flow
> @@ -3162,6 +3166,8 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb,
>                 }
>         }
>
> +try_rps:
> +
>         if (map) {
>                 tcpu = map->cpus[reciprocal_scale(hash, map->len)];
>                 if (cpu_online(tcpu)) {
> diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
> index fde21d19e61b..7a31be5e361f 100644
> --- a/net/core/sysctl_net_core.c
> +++ b/net/core/sysctl_net_core.c
> @@ -65,7 +65,7 @@ static int rps_sock_flow_sysctl(struct ctl_table *table, int write,
>                                         mutex_unlock(&sock_flow_mutex);
>                                         return -ENOMEM;
>                                 }
> -
> +                               rps_cpu_mask = roundup_pow_of_two(nr_cpu_ids) - 1;
>                                 sock_table->mask = size - 1;
>                         } else
>                                 sock_table = orig_sock_table;
> diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
> index a44773c8346c..d2e49baaff63 100644
> --- a/net/ipv4/af_inet.c
> +++ b/net/ipv4/af_inet.c
> @@ -395,8 +395,6 @@ int inet_release(struct socket *sock)
>         if (sk) {
>                 long timeout;
>
> -               sock_rps_reset_flow(sk);
> -
>                 /* Applications forget to leave groups before exiting */
>                 ip_mc_drop_socket(sk);
>
>
>

^ permalink raw reply

* Re: panic on boot with latest net-next
From: Josh Hunt @ 2015-02-06 22:11 UTC (permalink / raw)
  To: Thomas Graf; +Cc: herbert, netdev
In-Reply-To: <20150206221028.GA13706@casper.infradead.org>

On 02/06/2015 04:10 PM, Thomas Graf wrote:
> On 02/06/15 at 03:02pm, Josh Hunt wrote:
>> I'm hitting the following crash on boot with the latest net-next
>> (2ca292d968ef20cb04f31192d1f626bd8d782960):
>
> Thanks for the report.
>
> This should be fixed by the patches posted in the thread:
> [PATCH 0/6 v2 net-next] rhashtable fixes

Thanks. I will apply those and see if it resolves my issue.

Josh

^ permalink raw reply

* Re: panic on boot with latest net-next
From: Thomas Graf @ 2015-02-06 22:10 UTC (permalink / raw)
  To: Josh Hunt; +Cc: herbert, netdev
In-Reply-To: <54D52BD6.2080109@akamai.com>

On 02/06/15 at 03:02pm, Josh Hunt wrote:
> I'm hitting the following crash on boot with the latest net-next
> (2ca292d968ef20cb04f31192d1f626bd8d782960):

Thanks for the report.

This should be fixed by the patches posted in the thread:
[PATCH 0/6 v2 net-next] rhashtable fixes

^ permalink raw reply

* RE: [PATCH net-next v4] Add support of Cavium Liquidio ethernet adapters
From: Chickles, Derek @ 2015-02-06 20:28 UTC (permalink / raw)
  To: David Miller, Vatsavayi, Raghu
  Cc: netdev@vger.kernel.org, Burla, Satananda, Manlunas, Felix,
	Vatsavayi, Raghu
In-Reply-To: <20150202.190049.1051229698764700160.davem@davemloft.net>

> From: David Miller [mailto:davem@davemloft.net]
> Sent: Monday, February 02, 2015 7:01 PM
> >  create mode 100644
> drivers/net/ethernet/cavium/liquidio/cn66xx_device.c
>  ...
> >  create mode 100644
> drivers/net/ethernet/cavium/liquidio/cn68xx_device.c
> 
> These two file have several functions which are nearly identical.
> 
> Especially the device init register programming sequence.
> 
> Please consolidate the common code some more.
> 
> THanks.

Hi,

We've now consolidated 66xx and 68xx device init and access functions as
well as ethtool-related redundant stuff. This will come in a new patch
coming shortly.

Is there anything else you'd like to see us address?

Thanks,
Derek

^ permalink raw reply


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