* [PATCH v3 net-next 0/3] bridge: Add vlan filtering support for default pvid
From: Vladislav Yasevich @ 2014-10-02 23:54 UTC (permalink / raw)
To: netdev; +Cc: stephen, bridge, Vladislav Yasevich
This series adds default pvid support to vlan filtering in the bridge.
VLAN 1 (as recommended by 802.1q spec) is used as default pvid on ports.
The the user can over-ride this configuration by configuring their
own vlan information.
The user can additionally change the default value throught the
sysfs interface (netlink comming shortly).
The user can turn off default pvid functionality by setting default
pvid to 0.
This series changes the default behavior of the bridge when
vlan filtering is turned on. Currently, ports without any vlan
filtering configured will not recevie any traffic at all. This patch
changes the behavior of the above ports to receive only untagged traffic.
Since v2:
- Fix handling of invalid values in sysfs interface.
- Add some additional log messages.
- Fix default_pvid handling when vlan filtering is compiled out.
- Fix sparse issues with new code.
- Fix how we located the old default pvid (added a helper function).
Since v1:
- Add ability to turn off default_pvid settings.
- Drop the automiatic filtering support based on configured vlan devices (will
be its own series)
Thanks
-vlad
Vladislav Yasevich (3):
bridge: Add a default_pvid sysfs attribute
bridge: Simplify pvid checks.
bridge: Add filtering support for default_pvid
net/bridge/br_device.c | 8 ++-
net/bridge/br_if.c | 3 +
net/bridge/br_private.h | 23 ++++---
net/bridge/br_sysfs_br.c | 17 +++++
net/bridge/br_vlan.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++-
5 files changed, 197 insertions(+), 12 deletions(-)
--
1.9.3
^ permalink raw reply
* Re: [PATCH v1 5/5] driver-core: add driver asynchronous probe support
From: Luis R. Rodriguez @ 2014-10-02 23:31 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Luis R. Rodriguez, gregkh, tiwai, tj, arjan, teg, rmilasan,
werner, oleg, hare, bpoirier, santosh, pmladek, dbueso,
linux-kernel, Tetsuo Handa, Joseph Salisbury, Kay Sievers,
One Thousand Gnomes, Tim Gardner, Pierre Fersing, Andrew Morton,
Nagalakshmi Nandigama, Praveen Krishnamoorthy, Sreekanth Reddy,
Abhijit Mahajan, Casey Leedom
In-Reply-To: <20140930071555.GB14081@wotan.suse.de>
On Tue, Sep 30, 2014 at 09:15:55AM +0200, Luis R. Rodriguez wrote:
> Can you provide an example code path hit here? I'll certainly like to address
> that as well.
I managed to enable built-in driver support on top of this series,
I'll send them as part of the next series but I suspect we'll want
to discuss blacklist/whitelist a bit more there.
Luis
^ permalink raw reply
* Re: [PATCH v1 5/5] driver-core: add driver asynchronous probe support
From: Luis R. Rodriguez @ 2014-10-02 23:29 UTC (permalink / raw)
To: Tejun Heo
Cc: gregkh, Luis R. Rodriguez, dmitry.torokhov, tiwai, arjan, teg,
rmilasan, werner, oleg, hare, bpoirier, santosh, pmladek, dbueso,
linux-kernel, Tetsuo Handa, Joseph Salisbury, Kay Sievers,
One Thousand Gnomes, Tim Gardner, Pierre Fersing, Andrew Morton,
Nagalakshmi Nandigama, Praveen Krishnamoorthy, Sreekanth Reddy,
Abhijit Mahajan, Casey Leedom
In-Reply-To: <20140930072159.GC14081@wotan.suse.de>
On Tue, Sep 30, 2014 at 09:21:59AM +0200, Luis R. Rodriguez wrote:
> On Mon, Sep 29, 2014 at 05:26:01PM -0400, Tejun Heo wrote:
> > Hello, Luis.
> >
> > On Mon, Sep 29, 2014 at 11:22:08PM +0200, Luis R. Rodriguez wrote:
> > > > > + /* For now lets avoid stupid bug reports */
> > > > > + if (!strcmp(bus->name, "pci") ||
> > > > > + !strcmp(bus->name, "pci_express") ||
> > > > > + !strcmp(bus->name, "hid") ||
> > > > > + !strcmp(bus->name, "sdio") ||
> > > > > + !strcmp(bus->name, "gameport") ||
> > > > > + !strcmp(bus->name, "mmc") ||
> > > > > + !strcmp(bus->name, "i2c") ||
> > > > > + !strcmp(bus->name, "platform") ||
> > > > > + !strcmp(bus->name, "usb"))
> > > > > + return true;
> > > >
> > > > Ugh... things like this tend to become permanent. Do we really need
> > > > this? And how are we gonna find out what's broken why w/o bug
> > > > reports?
> > >
> > > Yeah... well we have two options, one is have something like this to
> > > at least make it generally useful or remove this and let folks who
> > > care start fixing async for all modules. The downside to removing
> > > this is it makes async probe pretty much useless on most systems
> > > right now, it would mean systemd would have to probably consider
> > > the list above if they wanted to start using this without expecting
> > > systems to not work.
> >
> > So, I'd much prefer blacklist approach if something like this is a
> > necessity. That way, we'd at least know what doesn't work.
>
> For buses? Or do you mean you'd want to wait until we have a decent
> list of drivers with the sync probe flag set? If the later it may take
> a while to get that list for this to be somewhat useful.
OK I'm removing this part and it works well for me now on my laptop
and an AMD server without a white list, so all the junk above will
be removed in the next series.
Luis
^ permalink raw reply
* Re: [PATCH v1 3/5] dtb: Add 10GbE node to APM X-Gene SoC device tree
From: Iyappan Subramanian @ 2014-10-02 23:24 UTC (permalink / raw)
To: Mark Rutland
Cc: davem@davemloft.net, netdev@vger.kernel.org,
devicetree@vger.kernel.org, kchudgar@apm.com, patches@apm.com
In-Reply-To: <20140924093727.GA9162@leverpostej>
On Wed, Sep 24, 2014 at 2:37 AM, Mark Rutland <mark.rutland@arm.com> wrote:
> Hi,
>
> For some reason, the below appears to use a mixture of spaces and tabs
> for alignment. Assuming my local mailserver isn't responsible for that,
> could you please correct that and for consistency use tabs?
>
> Could you also please Cc the arm64 maintainers when submitting arm64
> patches?
>
> On Wed, Sep 24, 2014 at 04:51:26AM +0100, Iyappan Subramanian wrote:
>> Added 10GbE interface and clock nodes.
>>
>> Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
>> ---
>> arch/arm64/boot/dts/apm-mustang.dts | 4 ++++
>> arch/arm64/boot/dts/apm-storm.dtsi | 24 ++++++++++++++++++++++++
>> 2 files changed, 28 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/apm-mustang.dts b/arch/arm64/boot/dts/apm-mustang.dts
>> index b2f5622..2ae782b 100644
>> --- a/arch/arm64/boot/dts/apm-mustang.dts
>> +++ b/arch/arm64/boot/dts/apm-mustang.dts
>> @@ -32,3 +32,7 @@
>> &menet {
>> status = "ok";
>> };
>> +
>> +&xgenet {
>> + status = "ok";
>> +};
>> diff --git a/arch/arm64/boot/dts/apm-storm.dtsi b/arch/arm64/boot/dts/apm-storm.dtsi
>> index c0aceef..ae814ef 100644
>> --- a/arch/arm64/boot/dts/apm-storm.dtsi
>> +++ b/arch/arm64/boot/dts/apm-storm.dtsi
>> @@ -176,6 +176,16 @@
>> clock-output-names = "menetclk";
>> };
>>
>> + xge0clk: xge0clk@1f61c000 {
>> + compatible = "apm,xgene-device-clock";
>> + #clock-cells = <1>;
>> + clocks = <&socplldiv2 0>;
>> + reg = <0x0 0x1f61c000 0x0 0x1000>;
>> + reg-names = "csr-reg";
>> + csr-mask = <0x3>;
>> + clock-output-names = "xge0clk";
>> + };
>> +
>> sataphy1clk: sataphy1clk@1f21c000 {
>> compatible = "apm,xgene-device-clock";
>> #clock-cells = <1>;
>> @@ -421,5 +431,19 @@
>>
>> };
>> };
>> +
>> + xgenet: ethernet@1f610000 {
>> + compatible = "apm,xgene-enet";
>> + status = "disabled";
>> + reg = <0x0 0x1f610000 0x0 0xd100>,
>> + <0x0 0x1f600000 0x0 0X400>,
>> + <0x0 0x18000000 0x0 0X200>;
>> + reg-names = "enet_csr", "ring_csr", "ring_cmd";
>> + interrupts = <0x0 0x60 0x4>;
>> + dma-coherent;
>> + clocks = <&xge0clk 0>;
>
>> + local-mac-address = [00 01 73 00 00 04];
>
> Does it really make sense to hard-code the same mac address for all
> mustang boards?
I tried to keep the OUI for the first 3 bytes. APM OUI = 00 01 73.
I noticed some other vendors dtbs have all 0's. Since they will get
overwritten by the bootloader, please suggest the preferred way.
>
> Mark.
>
>> + phy-connection-type = "xgmii";
>> + };
>> };
>> };
>> --
>> 1.9.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe devicetree" 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 v1 3/5] dtb: Add 10GbE node to APM X-Gene SoC device tree
From: Iyappan Subramanian @ 2014-10-02 23:17 UTC (permalink / raw)
To: Mark Rutland
Cc: davem@davemloft.net, netdev@vger.kernel.org,
devicetree@vger.kernel.org, kchudgar@apm.com, patches@apm.com
In-Reply-To: <20140924093727.GA9162@leverpostej>
On Wed, Sep 24, 2014 at 2:37 AM, Mark Rutland <mark.rutland@arm.com> wrote:
> Hi,
>
> For some reason, the below appears to use a mixture of spaces and tabs
> for alignment. Assuming my local mailserver isn't responsible for that,
> could you please correct that and for consistency use tabs?
I will correct the dtb. Somehow checkpatch.pl did not catch this.
>
> Could you also please Cc the arm64 maintainers when submitting arm64
> patches?
Sure. Thanks for pointing it out.
>
> On Wed, Sep 24, 2014 at 04:51:26AM +0100, Iyappan Subramanian wrote:
>> Added 10GbE interface and clock nodes.
>>
>> Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
>> ---
>> arch/arm64/boot/dts/apm-mustang.dts | 4 ++++
>> arch/arm64/boot/dts/apm-storm.dtsi | 24 ++++++++++++++++++++++++
>> 2 files changed, 28 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/apm-mustang.dts b/arch/arm64/boot/dts/apm-mustang.dts
>> index b2f5622..2ae782b 100644
>> --- a/arch/arm64/boot/dts/apm-mustang.dts
>> +++ b/arch/arm64/boot/dts/apm-mustang.dts
>> @@ -32,3 +32,7 @@
>> &menet {
>> status = "ok";
>> };
>> +
>> +&xgenet {
>> + status = "ok";
>> +};
>> diff --git a/arch/arm64/boot/dts/apm-storm.dtsi b/arch/arm64/boot/dts/apm-storm.dtsi
>> index c0aceef..ae814ef 100644
>> --- a/arch/arm64/boot/dts/apm-storm.dtsi
>> +++ b/arch/arm64/boot/dts/apm-storm.dtsi
>> @@ -176,6 +176,16 @@
>> clock-output-names = "menetclk";
>> };
>>
>> + xge0clk: xge0clk@1f61c000 {
>> + compatible = "apm,xgene-device-clock";
>> + #clock-cells = <1>;
>> + clocks = <&socplldiv2 0>;
>> + reg = <0x0 0x1f61c000 0x0 0x1000>;
>> + reg-names = "csr-reg";
>> + csr-mask = <0x3>;
>> + clock-output-names = "xge0clk";
>> + };
>> +
>> sataphy1clk: sataphy1clk@1f21c000 {
>> compatible = "apm,xgene-device-clock";
>> #clock-cells = <1>;
>> @@ -421,5 +431,19 @@
>>
>> };
>> };
>> +
>> + xgenet: ethernet@1f610000 {
>> + compatible = "apm,xgene-enet";
>> + status = "disabled";
>> + reg = <0x0 0x1f610000 0x0 0xd100>,
>> + <0x0 0x1f600000 0x0 0X400>,
>> + <0x0 0x18000000 0x0 0X200>;
>> + reg-names = "enet_csr", "ring_csr", "ring_cmd";
>> + interrupts = <0x0 0x60 0x4>;
>> + dma-coherent;
>> + clocks = <&xge0clk 0>;
>
>> + local-mac-address = [00 01 73 00 00 04];
>
> Does it really make sense to hard-code the same mac address for all
> mustang boards?
>
> Mark.
>
>> + phy-connection-type = "xgmii";
>> + };
>> };
>> };
>> --
>> 1.9.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe devicetree" 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] ipvs: Clean up comment style in ip_vs.h
From: Simon Horman @ 2014-10-02 23:13 UTC (permalink / raw)
To: Pablo Neira Ayuso
Cc: lvs-devel, netdev, netfilter-devel, Wensong Zhang,
Julian Anastasov, Sergei Shtylyov, David Miller
In-Reply-To: <20141002162324.GA4814@salvia>
On Thu, Oct 02, 2014 at 06:23:24PM +0200, Pablo Neira Ayuso wrote:
> Hi Simon,
>
> I made a second pass to your original patch. Mostly some leftovers and
> some missing line breaks that I added myself.
>
> Let me know if you have any objection with this, so I'll include this
> in the next batch that I'll send to David by tomorrow.
>
> Thanks.
Thanks Pablo,
that is fine by me.
> >From 87e9ac7144d529e6fd58dad1e222842b8de5ad8d Mon Sep 17 00:00:00 2001
> From: Simon Horman <horms@verge.net.au>
> Date: Tue, 30 Sep 2014 10:50:06 +0900
> Subject: [PATCH] ipvs: Clean up comment style in ip_vs.h
>
> * Consistently use the multi-line comment style for networking code:
>
> /* This
> * That
> * The other thing
> */
>
> * Use single-line comment style for comments with only one line of text.
>
> * In general follow the leading '*' of each line of a comment with a
> single space and then text.
>
> * Add missing line break between functions, remove double line break,
> align comments to previous lines whenever possible.
>
> Reported-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
> Signed-off-by: Simon Horman <horms@verge.net.au>
> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> ---
> include/net/ip_vs.h | 214 ++++++++++++++++++---------------------------------
> 1 file changed, 75 insertions(+), 139 deletions(-)
>
> diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
> index 576d7f0..615b20b 100644
> --- a/include/net/ip_vs.h
> +++ b/include/net/ip_vs.h
> @@ -1,6 +1,5 @@
> -/*
> - * IP Virtual Server
> - * data structure and functionality definitions
> +/* IP Virtual Server
> + * data structure and functionality definitions
> */
>
> #ifndef _NET_IP_VS_H
> @@ -12,7 +11,7 @@
>
> #include <linux/list.h> /* for struct list_head */
> #include <linux/spinlock.h> /* for struct rwlock_t */
> -#include <linux/atomic.h> /* for struct atomic_t */
> +#include <linux/atomic.h> /* for struct atomic_t */
> #include <linux/compiler.h>
> #include <linux/timer.h>
> #include <linux/bug.h>
> @@ -30,15 +29,13 @@
> #endif
> #include <net/net_namespace.h> /* Netw namespace */
>
> -/*
> - * Generic access of ipvs struct
> - */
> +/* Generic access of ipvs struct */
> static inline struct netns_ipvs *net_ipvs(struct net* net)
> {
> return net->ipvs;
> }
> -/*
> - * Get net ptr from skb in traffic cases
> +
> +/* Get net ptr from skb in traffic cases
> * use skb_sknet when call is from userland (ioctl or netlink)
> */
> static inline struct net *skb_net(const struct sk_buff *skb)
> @@ -90,8 +87,8 @@ static inline struct net *skb_sknet(const struct sk_buff *skb)
> return &init_net;
> #endif
> }
> -/*
> - * This one needed for single_open_net since net is stored directly in
> +
> +/* This one needed for single_open_net since net is stored directly in
> * private not as a struct i.e. seq_file_net can't be used.
> */
> static inline struct net *seq_file_single_net(struct seq_file *seq)
> @@ -108,7 +105,7 @@ extern int ip_vs_conn_tab_size;
>
> struct ip_vs_iphdr {
> __u32 len; /* IPv4 simply where L4 starts
> - IPv6 where L4 Transport Header starts */
> + * IPv6 where L4 Transport Header starts */
> __u16 fragoffs; /* IPv6 fragment offset, 0 if first frag (or not frag)*/
> __s16 protocol;
> __s32 flags;
> @@ -304,16 +301,11 @@ static inline const char *ip_vs_dbg_addr(int af, char *buf, size_t buf_len,
> #define LeaveFunction(level) do {} while (0)
> #endif
>
> -
> -/*
> - * The port number of FTP service (in network order).
> - */
> +/* The port number of FTP service (in network order). */
> #define FTPPORT cpu_to_be16(21)
> #define FTPDATA cpu_to_be16(20)
>
> -/*
> - * TCP State Values
> - */
> +/* TCP State Values */
> enum {
> IP_VS_TCP_S_NONE = 0,
> IP_VS_TCP_S_ESTABLISHED,
> @@ -329,25 +321,19 @@ enum {
> IP_VS_TCP_S_LAST
> };
>
> -/*
> - * UDP State Values
> - */
> +/* UDP State Values */
> enum {
> IP_VS_UDP_S_NORMAL,
> IP_VS_UDP_S_LAST,
> };
>
> -/*
> - * ICMP State Values
> - */
> +/* ICMP State Values */
> enum {
> IP_VS_ICMP_S_NORMAL,
> IP_VS_ICMP_S_LAST,
> };
>
> -/*
> - * SCTP State Values
> - */
> +/* SCTP State Values */
> enum ip_vs_sctp_states {
> IP_VS_SCTP_S_NONE,
> IP_VS_SCTP_S_INIT1,
> @@ -366,21 +352,18 @@ enum ip_vs_sctp_states {
> IP_VS_SCTP_S_LAST
> };
>
> -/*
> - * Delta sequence info structure
> - * Each ip_vs_conn has 2 (output AND input seq. changes).
> - * Only used in the VS/NAT.
> +/* Delta sequence info structure
> + * Each ip_vs_conn has 2 (output AND input seq. changes).
> + * Only used in the VS/NAT.
> */
> struct ip_vs_seq {
> __u32 init_seq; /* Add delta from this seq */
> __u32 delta; /* Delta in sequence numbers */
> __u32 previous_delta; /* Delta in sequence numbers
> - before last resized pkt */
> + * before last resized pkt */
> };
>
> -/*
> - * counters per cpu
> - */
> +/* counters per cpu */
> struct ip_vs_counters {
> __u32 conns; /* connections scheduled */
> __u32 inpkts; /* incoming packets */
> @@ -388,17 +371,13 @@ struct ip_vs_counters {
> __u64 inbytes; /* incoming bytes */
> __u64 outbytes; /* outgoing bytes */
> };
> -/*
> - * Stats per cpu
> - */
> +/* Stats per cpu */
> struct ip_vs_cpu_stats {
> struct ip_vs_counters ustats;
> struct u64_stats_sync syncp;
> };
>
> -/*
> - * IPVS statistics objects
> - */
> +/* IPVS statistics objects */
> struct ip_vs_estimator {
> struct list_head list;
>
> @@ -491,9 +470,7 @@ struct ip_vs_protocol {
> void (*timeout_change)(struct ip_vs_proto_data *pd, int flags);
> };
>
> -/*
> - * protocol data per netns
> - */
> +/* protocol data per netns */
> struct ip_vs_proto_data {
> struct ip_vs_proto_data *next;
> struct ip_vs_protocol *pp;
> @@ -520,9 +497,7 @@ struct ip_vs_conn_param {
> __u8 pe_data_len;
> };
>
> -/*
> - * IP_VS structure allocated for each dynamically scheduled connection
> - */
> +/* IP_VS structure allocated for each dynamically scheduled connection */
> struct ip_vs_conn {
> struct hlist_node c_list; /* hashed list heads */
> /* Protocol, addresses and port numbers */
> @@ -561,17 +536,18 @@ struct ip_vs_conn {
> struct ip_vs_dest *dest; /* real server */
> atomic_t in_pkts; /* incoming packet counter */
>
> - /* packet transmitter for different forwarding methods. If it
> - mangles the packet, it must return NF_DROP or better NF_STOLEN,
> - otherwise this must be changed to a sk_buff **.
> - NF_ACCEPT can be returned when destination is local.
> + /* Packet transmitter for different forwarding methods. If it
> + * mangles the packet, it must return NF_DROP or better NF_STOLEN,
> + * otherwise this must be changed to a sk_buff **.
> + * NF_ACCEPT can be returned when destination is local.
> */
> int (*packet_xmit)(struct sk_buff *skb, struct ip_vs_conn *cp,
> struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph);
>
> /* Note: we can group the following members into a structure,
> - in order to save more space, and the following members are
> - only used in VS/NAT anyway */
> + * in order to save more space, and the following members are
> + * only used in VS/NAT anyway
> + */
> struct ip_vs_app *app; /* bound ip_vs_app object */
> void *app_data; /* Application private data */
> struct ip_vs_seq in_seq; /* incoming seq. struct */
> @@ -584,9 +560,7 @@ struct ip_vs_conn {
> struct rcu_head rcu_head;
> };
>
> -/*
> - * To save some memory in conn table when name space is disabled.
> - */
> +/* To save some memory in conn table when name space is disabled. */
> static inline struct net *ip_vs_conn_net(const struct ip_vs_conn *cp)
> {
> #ifdef CONFIG_NET_NS
> @@ -595,6 +569,7 @@ static inline struct net *ip_vs_conn_net(const struct ip_vs_conn *cp)
> return &init_net;
> #endif
> }
> +
> static inline void ip_vs_conn_net_set(struct ip_vs_conn *cp, struct net *net)
> {
> #ifdef CONFIG_NET_NS
> @@ -612,13 +587,12 @@ static inline int ip_vs_conn_net_eq(const struct ip_vs_conn *cp,
> #endif
> }
>
> -/*
> - * Extended internal versions of struct ip_vs_service_user and
> - * ip_vs_dest_user for IPv6 support.
> +/* Extended internal versions of struct ip_vs_service_user and ip_vs_dest_user
> + * for IPv6 support.
> *
> - * We need these to conveniently pass around service and destination
> - * options, but unfortunately, we also need to keep the old definitions to
> - * maintain userspace backwards compatibility for the setsockopt interface.
> + * We need these to conveniently pass around service and destination
> + * options, but unfortunately, we also need to keep the old definitions to
> + * maintain userspace backwards compatibility for the setsockopt interface.
> */
> struct ip_vs_service_user_kern {
> /* virtual service addresses */
> @@ -656,8 +630,8 @@ struct ip_vs_dest_user_kern {
>
>
> /*
> - * The information about the virtual service offered to the net
> - * and the forwarding entries
> + * The information about the virtual service offered to the net and the
> + * forwarding entries.
> */
> struct ip_vs_service {
> struct hlist_node s_list; /* for normal service table */
> @@ -697,9 +671,8 @@ struct ip_vs_dest_dst {
> struct rcu_head rcu_head;
> };
>
> -/*
> - * The real server destination forwarding entry
> - * with ip address, port number, and so on.
> +/* The real server destination forwarding entry with ip address, port number,
> + * and so on.
> */
> struct ip_vs_dest {
> struct list_head n_list; /* for the dests in the service */
> @@ -738,10 +711,7 @@ struct ip_vs_dest {
> unsigned int in_rs_table:1; /* we are in rs_table */
> };
>
> -
> -/*
> - * The scheduler object
> - */
> +/* The scheduler object */
> struct ip_vs_scheduler {
> struct list_head n_list; /* d-linked list head */
> char *name; /* scheduler name */
> @@ -781,9 +751,7 @@ struct ip_vs_pe {
> int (*show_pe_data)(const struct ip_vs_conn *cp, char *buf);
> };
>
> -/*
> - * The application module object (a.k.a. app incarnation)
> - */
> +/* The application module object (a.k.a. app incarnation) */
> struct ip_vs_app {
> struct list_head a_list; /* member in app list */
> int type; /* IP_VS_APP_TYPE_xxx */
> @@ -799,16 +767,14 @@ struct ip_vs_app {
> atomic_t usecnt; /* usage counter */
> struct rcu_head rcu_head;
>
> - /*
> - * output hook: Process packet in inout direction, diff set for TCP.
> + /* output hook: Process packet in inout direction, diff set for TCP.
> * Return: 0=Error, 1=Payload Not Mangled/Mangled but checksum is ok,
> * 2=Mangled but checksum was not updated
> */
> int (*pkt_out)(struct ip_vs_app *, struct ip_vs_conn *,
> struct sk_buff *, int *diff);
>
> - /*
> - * input hook: Process packet in outin direction, diff set for TCP.
> + /* input hook: Process packet in outin direction, diff set for TCP.
> * Return: 0=Error, 1=Payload Not Mangled/Mangled but checksum is ok,
> * 2=Mangled but checksum was not updated
> */
> @@ -867,9 +833,7 @@ struct ipvs_master_sync_state {
> struct netns_ipvs {
> int gen; /* Generation */
> int enable; /* enable like nf_hooks do */
> - /*
> - * Hash table: for real service lookups
> - */
> + /* Hash table: for real service lookups */
> #define IP_VS_RTAB_BITS 4
> #define IP_VS_RTAB_SIZE (1 << IP_VS_RTAB_BITS)
> #define IP_VS_RTAB_MASK (IP_VS_RTAB_SIZE - 1)
> @@ -903,7 +867,7 @@ struct netns_ipvs {
> struct list_head sctp_apps[SCTP_APP_TAB_SIZE];
> #endif
> /* ip_vs_conn */
> - atomic_t conn_count; /* connection counter */
> + atomic_t conn_count; /* connection counter */
>
> /* ip_vs_ctl */
> struct ip_vs_stats tot_stats; /* Statistics & est. */
> @@ -990,9 +954,9 @@ struct netns_ipvs {
> char backup_mcast_ifn[IP_VS_IFNAME_MAXLEN];
> /* net name space ptr */
> struct net *net; /* Needed by timer routines */
> - /* Number of heterogeneous destinations, needed because
> - * heterogeneous are not supported when synchronization is
> - * enabled */
> + /* Number of heterogeneous destinations, needed becaus heterogeneous
> + * are not supported when synchronization is enabled.
> + */
> unsigned int mixed_address_family_dests;
> };
>
> @@ -1147,9 +1111,8 @@ static inline int sysctl_backup_only(struct netns_ipvs *ipvs)
>
> #endif
>
> -/*
> - * IPVS core functions
> - * (from ip_vs_core.c)
> +/* IPVS core functions
> + * (from ip_vs_core.c)
> */
> const char *ip_vs_proto_name(unsigned int proto);
> void ip_vs_init_hash_table(struct list_head *table, int rows);
> @@ -1157,11 +1120,9 @@ void ip_vs_init_hash_table(struct list_head *table, int rows);
>
> #define IP_VS_APP_TYPE_FTP 1
>
> -/*
> - * ip_vs_conn handling functions
> - * (from ip_vs_conn.c)
> +/* ip_vs_conn handling functions
> + * (from ip_vs_conn.c)
> */
> -
> enum {
> IP_VS_DIR_INPUT = 0,
> IP_VS_DIR_OUTPUT,
> @@ -1292,9 +1253,7 @@ ip_vs_control_add(struct ip_vs_conn *cp, struct ip_vs_conn *ctl_cp)
> atomic_inc(&ctl_cp->n_control);
> }
>
> -/*
> - * IPVS netns init & cleanup functions
> - */
> +/* IPVS netns init & cleanup functions */
> int ip_vs_estimator_net_init(struct net *net);
> int ip_vs_control_net_init(struct net *net);
> int ip_vs_protocol_net_init(struct net *net);
> @@ -1309,9 +1268,8 @@ void ip_vs_estimator_net_cleanup(struct net *net);
> void ip_vs_sync_net_cleanup(struct net *net);
> void ip_vs_service_net_cleanup(struct net *net);
>
> -/*
> - * IPVS application functions
> - * (from ip_vs_app.c)
> +/* IPVS application functions
> + * (from ip_vs_app.c)
> */
> #define IP_VS_APP_MAX_PORTS 8
> struct ip_vs_app *register_ip_vs_app(struct net *net, struct ip_vs_app *app);
> @@ -1331,9 +1289,7 @@ int unregister_ip_vs_pe(struct ip_vs_pe *pe);
> struct ip_vs_pe *ip_vs_pe_getbyname(const char *name);
> struct ip_vs_pe *__ip_vs_pe_getbyname(const char *pe_name);
>
> -/*
> - * Use a #define to avoid all of module.h just for these trivial ops
> - */
> +/* Use a #define to avoid all of module.h just for these trivial ops */
> #define ip_vs_pe_get(pe) \
> if (pe && pe->module) \
> __module_get(pe->module);
> @@ -1342,9 +1298,7 @@ struct ip_vs_pe *__ip_vs_pe_getbyname(const char *pe_name);
> if (pe && pe->module) \
> module_put(pe->module);
>
> -/*
> - * IPVS protocol functions (from ip_vs_proto.c)
> - */
> +/* IPVS protocol functions (from ip_vs_proto.c) */
> int ip_vs_protocol_init(void);
> void ip_vs_protocol_cleanup(void);
> void ip_vs_protocol_timeout_change(struct netns_ipvs *ipvs, int flags);
> @@ -1362,9 +1316,8 @@ extern struct ip_vs_protocol ip_vs_protocol_esp;
> extern struct ip_vs_protocol ip_vs_protocol_ah;
> extern struct ip_vs_protocol ip_vs_protocol_sctp;
>
> -/*
> - * Registering/unregistering scheduler functions
> - * (from ip_vs_sched.c)
> +/* Registering/unregistering scheduler functions
> + * (from ip_vs_sched.c)
> */
> int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler);
> int unregister_ip_vs_scheduler(struct ip_vs_scheduler *scheduler);
> @@ -1383,10 +1336,7 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
>
> void ip_vs_scheduler_err(struct ip_vs_service *svc, const char *msg);
>
> -
> -/*
> - * IPVS control data and functions (from ip_vs_ctl.c)
> - */
> +/* IPVS control data and functions (from ip_vs_ctl.c) */
> extern struct ip_vs_stats ip_vs_stats;
> extern int sysctl_ip_vs_sync_ver;
>
> @@ -1427,26 +1377,21 @@ static inline void ip_vs_dest_put_and_free(struct ip_vs_dest *dest)
> kfree(dest);
> }
>
> -/*
> - * IPVS sync daemon data and function prototypes
> - * (from ip_vs_sync.c)
> +/* IPVS sync daemon data and function prototypes
> + * (from ip_vs_sync.c)
> */
> int start_sync_thread(struct net *net, int state, char *mcast_ifn, __u8 syncid);
> int stop_sync_thread(struct net *net, int state);
> void ip_vs_sync_conn(struct net *net, struct ip_vs_conn *cp, int pkts);
>
> -/*
> - * IPVS rate estimator prototypes (from ip_vs_est.c)
> - */
> +/* IPVS rate estimator prototypes (from ip_vs_est.c) */
> void ip_vs_start_estimator(struct net *net, struct ip_vs_stats *stats);
> void ip_vs_stop_estimator(struct net *net, struct ip_vs_stats *stats);
> void ip_vs_zero_estimator(struct ip_vs_stats *stats);
> void ip_vs_read_estimator(struct ip_vs_stats_user *dst,
> struct ip_vs_stats *stats);
>
> -/*
> - * Various IPVS packet transmitters (from ip_vs_xmit.c)
> - */
> +/* Various IPVS packet transmitters (from ip_vs_xmit.c) */
> int ip_vs_null_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
> struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph);
> int ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
> @@ -1477,12 +1422,10 @@ int ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
> #endif
>
> #ifdef CONFIG_SYSCTL
> -/*
> - * This is a simple mechanism to ignore packets when
> - * we are loaded. Just set ip_vs_drop_rate to 'n' and
> - * we start to drop 1/rate of the packets
> +/* This is a simple mechanism to ignore packets when
> + * we are loaded. Just set ip_vs_drop_rate to 'n' and
> + * we start to drop 1/rate of the packets
> */
> -
> static inline int ip_vs_todrop(struct netns_ipvs *ipvs)
> {
> if (!ipvs->drop_rate)
> @@ -1496,9 +1439,7 @@ static inline int ip_vs_todrop(struct netns_ipvs *ipvs)
> static inline int ip_vs_todrop(struct netns_ipvs *ipvs) { return 0; }
> #endif
>
> -/*
> - * ip_vs_fwd_tag returns the forwarding tag of the connection
> - */
> +/* ip_vs_fwd_tag returns the forwarding tag of the connection */
> #define IP_VS_FWD_METHOD(cp) (cp->flags & IP_VS_CONN_F_FWD_MASK)
>
> static inline char ip_vs_fwd_tag(struct ip_vs_conn *cp)
> @@ -1557,9 +1498,7 @@ static inline __wsum ip_vs_check_diff2(__be16 old, __be16 new, __wsum oldsum)
> return csum_partial(diff, sizeof(diff), oldsum);
> }
>
> -/*
> - * Forget current conntrack (unconfirmed) and attach notrack entry
> - */
> +/* Forget current conntrack (unconfirmed) and attach notrack entry */
> static inline void ip_vs_notrack(struct sk_buff *skb)
> {
> #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
> @@ -1576,9 +1515,8 @@ static inline void ip_vs_notrack(struct sk_buff *skb)
> }
>
> #ifdef CONFIG_IP_VS_NFCT
> -/*
> - * Netfilter connection tracking
> - * (from ip_vs_nfct.c)
> +/* Netfilter connection tracking
> + * (from ip_vs_nfct.c)
> */
> static inline int ip_vs_conntrack_enabled(struct netns_ipvs *ipvs)
> {
> @@ -1617,14 +1555,12 @@ static inline int ip_vs_confirm_conntrack(struct sk_buff *skb)
> static inline void ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp)
> {
> }
> -/* CONFIG_IP_VS_NFCT */
> -#endif
> +#endif /* CONFIG_IP_VS_NFCT */
>
> static inline int
> ip_vs_dest_conn_overhead(struct ip_vs_dest *dest)
> {
> - /*
> - * We think the overhead of processing active connections is 256
> + /* We think the overhead of processing active connections is 256
> * times higher than that of inactive connections in average. (This
> * 256 times might not be accurate, we will change it later) We
> * use the following formula to estimate the overhead now:
> --
> 1.7.10.4
>
^ permalink raw reply
* Re: [PATCHv9 net-next 2/4] sunvnet: make transmit path zero-copy in the kernel
From: Raghuram Kothakota @ 2014-10-02 23:11 UTC (permalink / raw)
To: David L Stevens; +Cc: David Miller, netdev, Sowmini Varadhan
In-Reply-To: <542D32C4.8070703@oracle.com>
On Oct 2, 2014, at 4:11 AM, David L Stevens <david.stevens@oracle.com> wrote:
>
>
> On 10/02/2014 01:50 AM, Raghuram Kothakota wrote:
>
>
>>> + err = ldc_map_single(port->vio.lp, start, nlen,
>>> + port->tx_bufs[txi].cookies, 2,
>>> + (LDC_MAP_SHADOW | LDC_MAP_DIRECT | LDC_MAP_RW));
>>
>>
>> The LDC sharing protection mechanism is at a page level. If I understand
>> well, the vnet_skb_shape() function only addresses the alignment requirement
>> but it still leaves the possibility of exporting a lot more data than required to the
>> peer. This can be treated as a security issue, wondering if you thought of this issue.
>
> Since the specific offsets and lengths are provided in the API, I didn't realize that it was
> sharing more than the provided buffer until you pointed that out, before I submitted the
> patches. At that point, I considered it.
>
> The original buffers were ~1500 byte kzalloc'ed (for each buffer), meaning that they were
> potentially shared with arbitrary kernel memory on the same page.
That is not good as well, we do not want to share more than what the other guest
need to see.
-Raghuram
>
> This patch-set doesn't increase or decrease any security concerns related to oversharing
> with other LDOMs. The extents outside the provided buffers are (now) skbs, and so packet
> data, where before they could be any dynamically allocated kernel memory.
>
> +-DLS
^ permalink raw reply
* Re: [net-next 6/6] openvswitch: Add support for Geneve tunneling.
From: Tom Herbert @ 2014-10-02 23:04 UTC (permalink / raw)
To: Andy Zhou; +Cc: David Miller, Linux Netdev List, Jesse Gross
In-Reply-To: <1412237085-27215-7-git-send-email-azhou@nicira.com>
On Thu, Oct 2, 2014 at 1:04 AM, Andy Zhou <azhou@nicira.com> wrote:
> From: Jesse Gross <jesse@nicira.com>
>
> The Openvswitch implementation is completely agnostic to the options
> that are in use and can handle newly defined options without
> further work. It does this by simply matching on a byte array
> of options and allowing userspace to setup flows on this array.
>
> Signed-off-by: Jesse Gross <jesse@nicira.com>
> Signed-off-by: Andy Zhou <azhou@nicira.com>
> ---
> include/net/ip_tunnels.h | 21 ++--
> include/uapi/linux/openvswitch.h | 2 +
> net/openvswitch/Kconfig | 11 ++
> net/openvswitch/Makefile | 4 +
> net/openvswitch/datapath.c | 5 +-
> net/openvswitch/flow.c | 20 +++-
> net/openvswitch/flow.h | 20 +++-
> net/openvswitch/flow_netlink.c | 176 +++++++++++++++++++++++-----
> net/openvswitch/vport-geneve.c | 236 ++++++++++++++++++++++++++++++++++++++
> net/openvswitch/vport-gre.c | 2 +-
> net/openvswitch/vport-vxlan.c | 2 +-
> net/openvswitch/vport.c | 3 +
> net/openvswitch/vport.h | 1 +
> 13 files changed, 461 insertions(+), 42 deletions(-)
> create mode 100644 net/openvswitch/vport-geneve.c
>
> diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
> index a9ce155..5bc6ede 100644
> --- a/include/net/ip_tunnels.h
> +++ b/include/net/ip_tunnels.h
> @@ -86,17 +86,18 @@ struct ip_tunnel {
> struct gro_cells gro_cells;
> };
>
> -#define TUNNEL_CSUM __cpu_to_be16(0x01)
> -#define TUNNEL_ROUTING __cpu_to_be16(0x02)
> -#define TUNNEL_KEY __cpu_to_be16(0x04)
> -#define TUNNEL_SEQ __cpu_to_be16(0x08)
> -#define TUNNEL_STRICT __cpu_to_be16(0x10)
> -#define TUNNEL_REC __cpu_to_be16(0x20)
> -#define TUNNEL_VERSION __cpu_to_be16(0x40)
> -#define TUNNEL_NO_KEY __cpu_to_be16(0x80)
> +#define TUNNEL_CSUM __cpu_to_be16(0x01)
> +#define TUNNEL_ROUTING __cpu_to_be16(0x02)
> +#define TUNNEL_KEY __cpu_to_be16(0x04)
> +#define TUNNEL_SEQ __cpu_to_be16(0x08)
> +#define TUNNEL_STRICT __cpu_to_be16(0x10)
> +#define TUNNEL_REC __cpu_to_be16(0x20)
Just changing whitespace in these?
> +#define TUNNEL_VERSION __cpu_to_be16(0x40)
> +#define TUNNEL_NO_KEY __cpu_to_be16(0x80)
> #define TUNNEL_DONT_FRAGMENT __cpu_to_be16(0x0100)
> -#define TUNNEL_OAM __cpu_to_be16(0x0200)
> -#define TUNNEL_CRIT_OPT __cpu_to_be16(0x0400)
> +#define TUNNEL_OAM __cpu_to_be16(0x0200)
> +#define TUNNEL_CRIT_OPT __cpu_to_be16(0x0400)
> +#define TUNNEL_OPTIONS_PRESENT __cpu_to_be16(0x0800)
>
> struct tnl_ptk_info {
> __be16 flags;
> diff --git a/include/uapi/linux/openvswitch.h b/include/uapi/linux/openvswitch.h
> index 6753032..435eabc 100644
> --- a/include/uapi/linux/openvswitch.h
> +++ b/include/uapi/linux/openvswitch.h
> @@ -192,6 +192,7 @@ enum ovs_vport_type {
> OVS_VPORT_TYPE_INTERNAL, /* network device implemented by datapath */
> OVS_VPORT_TYPE_GRE, /* GRE tunnel. */
> OVS_VPORT_TYPE_VXLAN, /* VXLAN tunnel. */
> + OVS_VPORT_TYPE_GENEVE, /* Geneve tunnel. */
> __OVS_VPORT_TYPE_MAX
> };
>
> @@ -310,6 +311,7 @@ enum ovs_tunnel_key_attr {
> OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT, /* No argument, set DF. */
> OVS_TUNNEL_KEY_ATTR_CSUM, /* No argument. CSUM packet. */
> OVS_TUNNEL_KEY_ATTR_OAM, /* No argument. OAM frame. */
> + OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS, /* Array of Geneve options. */
> __OVS_TUNNEL_KEY_ATTR_MAX
> };
>
> diff --git a/net/openvswitch/Kconfig b/net/openvswitch/Kconfig
> index 6ecf491..ba3bb82 100644
> --- a/net/openvswitch/Kconfig
> +++ b/net/openvswitch/Kconfig
> @@ -54,3 +54,14 @@ config OPENVSWITCH_VXLAN
> Say N to exclude this support and reduce the binary size.
>
> If unsure, say Y.
> +
> +config OPENVSWITCH_GENEVE
> + bool "Open vSwitch Geneve tunneling support"
> + depends on INET
> + depends on OPENVSWITCH
> + depends on GENEVE && !(OPENVSWITCH=y && GENEVE=m)
> + default y
> + ---help---
> + If you say Y here, then the Open vSwitch will be able create geneve vport.
> +
> + Say N to exclude this support and reduce the binary size.
> diff --git a/net/openvswitch/Makefile b/net/openvswitch/Makefile
> index 3591cb5..9a33a27 100644
> --- a/net/openvswitch/Makefile
> +++ b/net/openvswitch/Makefile
> @@ -15,6 +15,10 @@ openvswitch-y := \
> vport-internal_dev.o \
> vport-netdev.o
>
> +ifneq ($(CONFIG_OPENVSWITCH_GENEVE),)
> +openvswitch-y += vport-geneve.o
> +endif
> +
> ifneq ($(CONFIG_OPENVSWITCH_VXLAN),)
> openvswitch-y += vport-vxlan.o
> endif
> diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
> index 010125c..2e31d9e 100644
> --- a/net/openvswitch/datapath.c
> +++ b/net/openvswitch/datapath.c
> @@ -370,6 +370,7 @@ static size_t key_attr_size(void)
> + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT */
> + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_CSUM */
> + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_OAM */
> + + nla_total_size(256) /* OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS */
> + nla_total_size(4) /* OVS_KEY_ATTR_IN_PORT */
> + nla_total_size(4) /* OVS_KEY_ATTR_SKB_MARK */
> + nla_total_size(12) /* OVS_KEY_ATTR_ETHERNET */
> @@ -556,10 +557,12 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
>
> err = ovs_nla_copy_actions(a[OVS_PACKET_ATTR_ACTIONS],
> &flow->key, 0, &acts);
> - rcu_assign_pointer(flow->sf_acts, acts);
> if (err)
> goto err_flow_free;
>
> + rcu_assign_pointer(flow->sf_acts, acts);
> +
> + OVS_CB(packet)->egress_tun_info = NULL;
> OVS_CB(packet)->flow = flow;
> packet->priority = flow->key.phy.priority;
> packet->mark = flow->key.phy.skb_mark;
> diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
> index 2924cb3..62db02b 100644
> --- a/net/openvswitch/flow.c
> +++ b/net/openvswitch/flow.c
> @@ -448,6 +448,9 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
> int error;
> struct ethhdr *eth;
>
> + /* Flags are always used as part of stats */
> + key->tp.flags = 0;
> +
> skb_reset_mac_header(skb);
>
> /* Link layer. We are guaranteed to have at least the 14 byte Ethernet
> @@ -646,10 +649,23 @@ int ovs_flow_key_extract(struct ovs_tunnel_info *tun_info,
> struct sk_buff *skb, struct sw_flow_key *key)
> {
> /* Extract metadata from packet. */
> - if (tun_info)
> + if (tun_info) {
> memcpy(&key->tun_key, &tun_info->tunnel, sizeof(key->tun_key));
> - else
> +
> + if (tun_info->options) {
> + BUILD_BUG_ON((1 << (sizeof(tun_info->options_len) *
> + 8)) - 1
> + > sizeof(key->tun_opts));
> + memcpy(GENEVE_OPTS(key, tun_info->options_len),
> + tun_info->options, tun_info->options_len);
> + key->tun_opts_len = tun_info->options_len;
> + } else {
> + key->tun_opts_len = 0;
> + }
> + } else {
> + key->tun_opts_len = 0;
> memset(&key->tun_key, 0, sizeof(key->tun_key));
> + }
>
> key->phy.priority = skb->priority;
> key->phy.in_port = OVS_CB(skb)->input_vport->port_no;
> diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h
> index fe5a71b..7181331 100644
> --- a/net/openvswitch/flow.h
> +++ b/net/openvswitch/flow.h
> @@ -51,11 +51,24 @@ struct ovs_key_ipv4_tunnel {
>
> struct ovs_tunnel_info {
> struct ovs_key_ipv4_tunnel tunnel;
> + struct geneve_opt *options;
> + u8 options_len;
> };
>
> +/* Store options at the end of the array if they are less than the
> + * maximum size. This allows us to get the benefits of variable length
> + * matching for small options.
> + */
> +#define GENEVE_OPTS(flow_key, opt_len) \
> + ((struct geneve_opt *)((flow_key)->tun_opts + \
> + FIELD_SIZEOF(struct sw_flow_key, tun_opts) - \
> + opt_len))
> +
> static inline void ovs_flow_tun_info_init(struct ovs_tunnel_info *tun_info,
> const struct iphdr *iph,
> - __be64 tun_id, __be16 tun_flags)
> + __be64 tun_id, __be16 tun_flags,
> + struct geneve_opt *opts,
> + u8 opts_len)
> {
> tun_info->tunnel.tun_id = tun_id;
> tun_info->tunnel.ipv4_src = iph->saddr;
> @@ -67,9 +80,14 @@ static inline void ovs_flow_tun_info_init(struct ovs_tunnel_info *tun_info,
> /* clear struct padding. */
> memset((unsigned char *)&tun_info->tunnel + OVS_TUNNEL_KEY_SIZE, 0,
> sizeof(tun_info->tunnel) - OVS_TUNNEL_KEY_SIZE);
> +
> + tun_info->options = opts;
> + tun_info->options_len = opts_len;
> }
>
> struct sw_flow_key {
> + u8 tun_opts[255];
> + u8 tun_opts_len;
> struct ovs_key_ipv4_tunnel tun_key; /* Encapsulating tunnel key. */
> struct {
> u32 priority; /* Packet QoS priority. */
> diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
> index 5d6194d..368f233 100644
> --- a/net/openvswitch/flow_netlink.c
> +++ b/net/openvswitch/flow_netlink.c
> @@ -42,6 +42,7 @@
> #include <linux/icmp.h>
> #include <linux/icmpv6.h>
> #include <linux/rculist.h>
> +#include <net/geneve.h>
> #include <net/ip.h>
> #include <net/ipv6.h>
> #include <net/ndisc.h>
> @@ -88,18 +89,20 @@ static void update_range__(struct sw_flow_match *match,
> } \
> } while (0)
>
> -#define SW_FLOW_KEY_MEMCPY(match, field, value_p, len, is_mask) \
> - do { \
> - update_range__(match, offsetof(struct sw_flow_key, field), \
> - len, is_mask); \
> - if (is_mask) { \
> - if ((match)->mask) \
> - memcpy(&(match)->mask->key.field, value_p, len);\
> - } else { \
> - memcpy(&(match)->key->field, value_p, len); \
> - } \
> +#define SW_FLOW_KEY_MEMCPY_OFFSET(match, offset, value_p, len, is_mask) \
> + do { \
> + update_range__(match, offset, len, is_mask); \
> + if (is_mask) \
> + memcpy((u8 *)&(match)->mask->key + offset, value_p, \
> + len); \
> + else \
> + memcpy((u8 *)(match)->key + offset, value_p, len); \
> } while (0)
>
> +#define SW_FLOW_KEY_MEMCPY(match, field, value_p, len, is_mask) \
> + SW_FLOW_KEY_MEMCPY_OFFSET(match, offsetof(struct sw_flow_key, field), \
> + value_p, len, is_mask)
> +
> static u16 range_n_bytes(const struct sw_flow_key_range *range)
> {
> return range->end - range->start;
> @@ -335,6 +338,7 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr,
> int rem;
> bool ttl = false;
> __be16 tun_flags = 0;
> + unsigned long opt_key_offset;
>
> nla_for_each_nested(a, attr, rem) {
> int type = nla_type(a);
> @@ -347,6 +351,7 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr,
> [OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT] = 0,
> [OVS_TUNNEL_KEY_ATTR_CSUM] = 0,
> [OVS_TUNNEL_KEY_ATTR_OAM] = 0,
> + [OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS] = -1,
> };
>
> if (type > OVS_TUNNEL_KEY_ATTR_MAX) {
> @@ -355,7 +360,8 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr,
> return -EINVAL;
> }
>
> - if (ovs_tunnel_key_lens[type] != nla_len(a)) {
> + if (ovs_tunnel_key_lens[type] != nla_len(a) &&
> + ovs_tunnel_key_lens[type] != -1) {
> OVS_NLERR("IPv4 tunnel attribute type has unexpected "
> " length (type=%d, length=%d, expected=%d).\n",
> type, nla_len(a), ovs_tunnel_key_lens[type]);
> @@ -394,7 +400,60 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr,
> case OVS_TUNNEL_KEY_ATTR_OAM:
> tun_flags |= TUNNEL_OAM;
> break;
> + case OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS:
> + tun_flags |= TUNNEL_OPTIONS_PRESENT;
> + if (nla_len(a) > sizeof(match->key->tun_opts)) {
> + OVS_NLERR("Geneve option length exceeds maximum size (len %d, max %zu).\n",
> + nla_len(a),
> + sizeof(match->key->tun_opts));
> + return -EINVAL;
> + }
> +
> + if (nla_len(a) % 4 != 0) {
> + OVS_NLERR("Geneve option length is not a multiple of 4 (len %d).\n",
> + nla_len(a));
> + return -EINVAL;
> + }
> +
> + /* We need to record the length of the options passed
> + * down, otherwise packets with the same format but
> + * additional options will be silently matched.
> + */
> + if (!is_mask) {
> + SW_FLOW_KEY_PUT(match, tun_opts_len, nla_len(a),
> + false);
> + } else {
> + /* This is somewhat unusual because it looks at
> + * both the key and mask while parsing the
> + * attributes (and by extension assumes the key
> + * is parsed first). Normally, we would verify
> + * that each is the correct length and that the
> + * attributes line up in the validate function.
> + * However, that is difficult because this is
> + * variable length and we won't have the
> + * information later.
> + */
> + if (match->key->tun_opts_len != nla_len(a)) {
> + OVS_NLERR("Geneve option key length (%d) is different from mask length (%d).",
> + match->key->tun_opts_len,
> + nla_len(a));
> + return -EINVAL;
> + }
> +
> + SW_FLOW_KEY_PUT(match, tun_opts_len, 0xff,
> + true);
> + }
> +
> + opt_key_offset = (unsigned long)GENEVE_OPTS(
> + (struct sw_flow_key *)0,
> + nla_len(a));
> + SW_FLOW_KEY_MEMCPY_OFFSET(match, opt_key_offset,
> + nla_data(a), nla_len(a),
> + is_mask);
> + break;
> default:
> + OVS_NLERR("Unknown IPv4 tunnel attribute (%d).\n",
> + type);
> return -EINVAL;
> }
> }
> @@ -421,16 +480,11 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr,
> return 0;
> }
>
> -static int ipv4_tun_to_nlattr(struct sk_buff *skb,
> - const struct ovs_key_ipv4_tunnel *tun_key,
> - const struct ovs_key_ipv4_tunnel *output)
> +static int __ipv4_tun_to_nlattr(struct sk_buff *skb,
> + const struct ovs_key_ipv4_tunnel *output,
> + const struct geneve_opt *tun_opts,
> + int swkey_tun_opts_len)
> {
> - struct nlattr *nla;
> -
> - nla = nla_nest_start(skb, OVS_KEY_ATTR_TUNNEL);
> - if (!nla)
> - return -EMSGSIZE;
> -
> if (output->tun_flags & TUNNEL_KEY &&
> nla_put_be64(skb, OVS_TUNNEL_KEY_ATTR_ID, output->tun_id))
> return -EMSGSIZE;
> @@ -454,12 +508,35 @@ static int ipv4_tun_to_nlattr(struct sk_buff *skb,
> if ((output->tun_flags & TUNNEL_OAM) &&
> nla_put_flag(skb, OVS_TUNNEL_KEY_ATTR_OAM))
> return -EMSGSIZE;
> + if (tun_opts &&
> + nla_put(skb, OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS,
> + swkey_tun_opts_len, tun_opts))
> + return -EMSGSIZE;
>
> - nla_nest_end(skb, nla);
> return 0;
> }
>
>
> +static int ipv4_tun_to_nlattr(struct sk_buff *skb,
> + const struct ovs_key_ipv4_tunnel *output,
> + const struct geneve_opt *tun_opts,
> + int swkey_tun_opts_len)
> +{
> + struct nlattr *nla;
> + int err;
> +
> + nla = nla_nest_start(skb, OVS_KEY_ATTR_TUNNEL);
> + if (!nla)
> + return -EMSGSIZE;
> +
> + err = __ipv4_tun_to_nlattr(skb, output, tun_opts, swkey_tun_opts_len);
> + if (err)
> + return err;
> +
> + nla_nest_end(skb, nla);
> + return 0;
> +}
> +
> static int metadata_from_nlattrs(struct sw_flow_match *match, u64 *attrs,
> const struct nlattr **a, bool is_mask)
> {
> @@ -905,9 +982,16 @@ int ovs_nla_put_flow(const struct sw_flow_key *swkey,
> if (nla_put_u32(skb, OVS_KEY_ATTR_PRIORITY, output->phy.priority))
> goto nla_put_failure;
>
> - if ((swkey->tun_key.ipv4_dst || is_mask) &&
> - ipv4_tun_to_nlattr(skb, &swkey->tun_key, &output->tun_key))
> - goto nla_put_failure;
> + if ((swkey->tun_key.ipv4_dst || is_mask)) {
> + const struct geneve_opt *opts = NULL;
> +
> + if (output->tun_key.tun_flags & TUNNEL_OPTIONS_PRESENT)
> + opts = GENEVE_OPTS(output, swkey->tun_opts_len);
> +
> + if (ipv4_tun_to_nlattr(skb, &output->tun_key, opts,
> + swkey->tun_opts_len))
> + goto nla_put_failure;
> + }
>
> if (swkey->phy.in_port == DP_MAX_PORTS) {
> if (is_mask && (output->phy.in_port == 0xffff))
> @@ -1290,17 +1374,55 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
> if (err)
> return err;
>
> + if (key.tun_opts_len) {
> + struct geneve_opt *option = GENEVE_OPTS(&key,
> + key.tun_opts_len);
> + int opts_len = key.tun_opts_len;
> + bool crit_opt = false;
> +
> + while (opts_len > 0) {
> + int len;
> +
> + if (opts_len < sizeof(*option))
> + return -EINVAL;
> +
> + len = sizeof(*option) + option->length * 4;
> + if (len > opts_len)
> + return -EINVAL;
> +
> + crit_opt |= !!(option->type & GENEVE_CRIT_OPT_TYPE);
> +
> + option = (struct geneve_opt *)((u8 *)option + len);
> + opts_len -= len;
> + };
> +
> + key.tun_key.tun_flags |= crit_opt ? TUNNEL_CRIT_OPT : 0;
> + };
> +
> start = add_nested_action_start(sfa, OVS_ACTION_ATTR_SET);
> if (start < 0)
> return start;
>
> a = __add_action(sfa, OVS_KEY_ATTR_TUNNEL_INFO, NULL,
> - sizeof(*tun_info));
> + sizeof(*tun_info) + key.tun_opts_len);
> if (IS_ERR(a))
> return PTR_ERR(a);
>
> tun_info = nla_data(a);
> tun_info->tunnel = key.tun_key;
> + tun_info->options_len = key.tun_opts_len;
> +
> + if (tun_info->options_len) {
> + /* We need to store the options in the action itself since
> + * everything else will go away after flow setup. We can append
> + * it to tun_info and then point there.
> + */
> + memcpy((tun_info + 1), GENEVE_OPTS(&key, key.tun_opts_len),
> + key.tun_opts_len);
> + tun_info->options = (struct geneve_opt *)(tun_info + 1);
> + } else {
> + tun_info->options = NULL;
> + }
>
> add_nested_action_end(*sfa, start);
>
> @@ -1592,7 +1714,9 @@ static int set_action_to_attr(const struct nlattr *a, struct sk_buff *skb)
> return -EMSGSIZE;
>
> err = ipv4_tun_to_nlattr(skb, &tun_info->tunnel,
> - nla_data(ovs_key));
> + tun_info->options_len ?
> + tun_info->options : NULL,
> + tun_info->options_len);
> if (err)
> return err;
> nla_nest_end(skb, start);
> diff --git a/net/openvswitch/vport-geneve.c b/net/openvswitch/vport-geneve.c
> new file mode 100644
> index 0000000..5572d48
> --- /dev/null
> +++ b/net/openvswitch/vport-geneve.c
> @@ -0,0 +1,236 @@
> +/*
> + * Copyright (c) 2014 Nicira, Inc.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + */
> +
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> +#include <linux/version.h>
> +
> +#include <linux/in.h>
> +#include <linux/ip.h>
> +#include <linux/net.h>
> +#include <linux/rculist.h>
> +#include <linux/udp.h>
> +#include <linux/if_vlan.h>
> +
> +#include <net/geneve.h>
> +#include <net/icmp.h>
> +#include <net/ip.h>
> +#include <net/route.h>
> +#include <net/udp.h>
> +#include <net/xfrm.h>
> +
> +#include "datapath.h"
> +#include "vport.h"
> +
> +/**
> + * struct geneve_port - Keeps track of open UDP ports
> + * @sock: The socket created for this port number.
> + * @name: vport name.
> + */
> +struct geneve_port {
> + struct geneve_sock *gs;
> + char name[IFNAMSIZ];
> +};
> +
> +static LIST_HEAD(geneve_ports);
> +
> +static inline struct geneve_port *geneve_vport(const struct vport *vport)
> +{
> + return vport_priv(vport);
> +}
> +
> +static inline struct genevehdr *geneve_hdr(const struct sk_buff *skb)
> +{
> + return (struct genevehdr *)(udp_hdr(skb) + 1);
> +}
> +
> +/* Convert 64 bit tunnel ID to 24 bit VNI. */
> +static void tunnel_id_to_vni(__be64 tun_id, __u8 *vni)
> +{
> +#ifdef __BIG_ENDIAN
> + vni[0] = (__force __u8)(tun_id >> 16);
> + vni[1] = (__force __u8)(tun_id >> 8);
> + vni[2] = (__force __u8)tun_id;
> +#else
> + vni[0] = (__force __u8)((__force u64)tun_id >> 40);
> + vni[1] = (__force __u8)((__force u64)tun_id >> 48);
> + vni[2] = (__force __u8)((__force u64)tun_id >> 56);
> +#endif
> +}
> +
> +/* Convert 24 bit VNI to 64 bit tunnel ID. */
> +static __be64 vni_to_tunnel_id(__u8 *vni)
> +{
> +#ifdef __BIG_ENDIAN
> + return (vni[0] << 16) | (vni[1] << 8) | vni[2];
> +#else
> + return (__force __be64)(((__force u64)vni[0] << 40) |
> + ((__force u64)vni[1] << 48) |
> + ((__force u64)vni[2] << 56));
> +#endif
> +}
> +
> +static void geneve_rcv(struct geneve_sock *gs, struct sk_buff *skb)
> +{
> + struct vport *vport = gs->rcv_data;
> + struct genevehdr *geneveh = geneve_hdr(skb);
> + int opts_len;
> + struct ovs_tunnel_info tun_info;
> + __be64 key;
> + __be16 flags;
> +
> + opts_len = geneveh->opt_len * 4;
> +
> + flags = TUNNEL_KEY | TUNNEL_OPTIONS_PRESENT |
> + (udp_hdr(skb)->check != 0 ? TUNNEL_CSUM : 0) |
> + (geneveh->oam ? TUNNEL_OAM : 0) |
> + (geneveh->critical ? TUNNEL_CRIT_OPT : 0);
> +
> + key = vni_to_tunnel_id(geneveh->vni);
> +
> + ovs_flow_tun_info_init(&tun_info, ip_hdr(skb), key, flags,
> + geneveh->options, opts_len);
> +
> + ovs_vport_receive(vport, skb, &tun_info);
> +}
> +
> +static int geneve_get_options(const struct vport *vport,
> + struct sk_buff *skb)
> +{
> + struct geneve_port *geneve_port = geneve_vport(vport);
> + __be16 sport;
> +
> + sport = ntohs(inet_sk(geneve_port->gs->sock->sk)->inet_sport);
> + if (nla_put_u16(skb, OVS_TUNNEL_ATTR_DST_PORT, sport))
> + return -EMSGSIZE;
> + return 0;
> +}
> +
> +static void geneve_tnl_destroy(struct vport *vport)
> +{
> + struct geneve_port *geneve_port = geneve_vport(vport);
> +
> + geneve_sock_release(geneve_port->gs);
> +
> + ovs_vport_deferred_free(vport);
> +}
> +
> +static struct vport *geneve_tnl_create(const struct vport_parms *parms)
> +{
> + struct net *net = ovs_dp_get_net(parms->dp);
> + struct nlattr *options = parms->options;
> + struct geneve_port *geneve_port;
> + struct geneve_sock *gs;
> + struct vport *vport;
> + struct nlattr *a;
> + int err;
> + u16 dst_port;
> +
> + if (!options) {
> + err = -EINVAL;
> + goto error;
> + }
> +
> + a = nla_find_nested(options, OVS_TUNNEL_ATTR_DST_PORT);
> + if (a && nla_len(a) == sizeof(u16)) {
> + dst_port = nla_get_u16(a);
> + } else {
> + /* Require destination port from userspace. */
> + err = -EINVAL;
> + goto error;
> + }
> +
> + vport = ovs_vport_alloc(sizeof(struct geneve_port),
> + &ovs_geneve_vport_ops, parms);
> + if (IS_ERR(vport))
> + return vport;
> +
> + geneve_port = geneve_vport(vport);
> + strncpy(geneve_port->name, parms->name, IFNAMSIZ);
> +
> + gs = geneve_sock_add(net, htons(dst_port), geneve_rcv, vport, true, 0);
> + if (IS_ERR(gs)) {
> + ovs_vport_free(vport);
> + return (void *)gs;
> + }
> + geneve_port->gs = gs;
> +
> + return vport;
> +error:
> + return ERR_PTR(err);
> +}
> +
> +static int geneve_tnl_send(struct vport *vport, struct sk_buff *skb)
> +{
> + struct ovs_key_ipv4_tunnel *tun_key;
> + struct ovs_tunnel_info *tun_info;
> + struct net *net = ovs_dp_get_net(vport->dp);
> + struct geneve_port *geneve_port = geneve_vport(vport);
> + __be16 dport = inet_sk(geneve_port->gs->sock->sk)->inet_sport;
> + __be16 sport;
> + struct rtable *rt;
> + struct flowi4 fl;
> + u8 vni[3];
> + __be16 df;
> + int err;
> +
> + tun_info = OVS_CB(skb)->egress_tun_info;
> + if (unlikely(!tun_info)) {
> + err = -EINVAL;
> + goto error;
> + }
> +
> + tun_key = &tun_info->tunnel;
> +
> + /* Route lookup */
> + memset(&fl, 0, sizeof(fl));
> + fl.daddr = tun_key->ipv4_dst;
> + fl.saddr = tun_key->ipv4_src;
> + fl.flowi4_tos = RT_TOS(tun_key->ipv4_tos);
> + fl.flowi4_mark = skb->mark;
> + fl.flowi4_proto = IPPROTO_UDP;
> +
> + rt = ip_route_output_key(net, &fl);
> + if (IS_ERR(rt)) {
> + err = PTR_ERR(rt);
> + goto error;
> + }
> +
> + df = tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
> + sport = udp_flow_src_port(net, skb, 1, USHRT_MAX, true);
> + tunnel_id_to_vni(tun_key->tun_id, vni);
> + skb->ignore_df = 1;
> +
> + err = geneve_xmit_skb(geneve_port->gs, rt, skb, fl.saddr,
> + tun_key->ipv4_dst, tun_key->ipv4_tos,
> + tun_key->ipv4_ttl, df, sport, dport,
> + tun_key->tun_flags, vni,
> + tun_info->options_len, (u8 *)tun_info->options,
> + false);
> + if (err < 0)
> + ip_rt_put(rt);
> +error:
> + return err;
> +}
> +
> +static const char *geneve_get_name(const struct vport *vport)
> +{
> + struct geneve_port *geneve_port = geneve_vport(vport);
> +
> + return geneve_port->name;
> +}
> +
> +const struct vport_ops ovs_geneve_vport_ops = {
> + .type = OVS_VPORT_TYPE_GENEVE,
> + .create = geneve_tnl_create,
> + .destroy = geneve_tnl_destroy,
> + .get_name = geneve_get_name,
> + .get_options = geneve_get_options,
> + .send = geneve_tnl_send,
> +};
> diff --git a/net/openvswitch/vport-gre.c b/net/openvswitch/vport-gre.c
> index fe768bd..108b82d 100644
> --- a/net/openvswitch/vport-gre.c
> +++ b/net/openvswitch/vport-gre.c
> @@ -106,7 +106,7 @@ static int gre_rcv(struct sk_buff *skb,
>
> key = key_to_tunnel_id(tpi->key, tpi->seq);
> ovs_flow_tun_info_init(&tun_info, ip_hdr(skb), key,
> - filter_tnl_flags(tpi->flags));
> + filter_tnl_flags(tpi->flags), NULL, 0);
>
> ovs_vport_receive(vport, skb, &tun_info);
> return PACKET_RCVD;
> diff --git a/net/openvswitch/vport-vxlan.c b/net/openvswitch/vport-vxlan.c
> index 5fbff2c..2735e01 100644
> --- a/net/openvswitch/vport-vxlan.c
> +++ b/net/openvswitch/vport-vxlan.c
> @@ -66,7 +66,7 @@ static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb, __be32 vx_vni)
> /* Save outer tunnel values */
> iph = ip_hdr(skb);
> key = cpu_to_be64(ntohl(vx_vni) >> 8);
> - ovs_flow_tun_info_init(&tun_info, iph, key, TUNNEL_KEY);
> + ovs_flow_tun_info_init(&tun_info, iph, key, TUNNEL_KEY, NULL, 0);
>
> ovs_vport_receive(vport, skb, &tun_info);
> }
> diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c
> index 3e50ee8..53001b0 100644
> --- a/net/openvswitch/vport.c
> +++ b/net/openvswitch/vport.c
> @@ -48,6 +48,9 @@ static const struct vport_ops *vport_ops_list[] = {
> #ifdef CONFIG_OPENVSWITCH_VXLAN
> &ovs_vxlan_vport_ops,
> #endif
> +#ifdef CONFIG_OPENVSWITCH_GENEVE
> + &ovs_geneve_vport_ops,
> +#endif
> };
>
> /* Protected by RCU read lock for reading, ovs_mutex for writing. */
> diff --git a/net/openvswitch/vport.h b/net/openvswitch/vport.h
> index e28964a..8942125 100644
> --- a/net/openvswitch/vport.h
> +++ b/net/openvswitch/vport.h
> @@ -215,6 +215,7 @@ extern const struct vport_ops ovs_netdev_vport_ops;
> extern const struct vport_ops ovs_internal_vport_ops;
> extern const struct vport_ops ovs_gre_vport_ops;
> extern const struct vport_ops ovs_vxlan_vport_ops;
> +extern const struct vport_ops ovs_geneve_vport_ops;
>
> static inline void ovs_skb_postpush_rcsum(struct sk_buff *skb,
> const void *start, unsigned int len)
> --
> 1.7.9.5
>
> --
> 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
* [PATCH net-next v2 2/2] enic: add vmname port-profile handler
From: Govindarajulu Varadarajan @ 2014-10-02 22:41 UTC (permalink / raw)
To: davem, netdev; +Cc: ssujith, benve, Govindarajulu Varadarajan
In-Reply-To: <1412289683-8278-1-git-send-email-_govind@gmx.com>
This patch adds support to read vmname from port-profile netlink message and
send it to firmware.
Signed-off-by: Govindarajulu Varadarajan <_govind@gmx.com>
---
drivers/net/ethernet/cisco/enic/enic.h | 2 ++
drivers/net/ethernet/cisco/enic/enic_main.c | 6 ++++++
drivers/net/ethernet/cisco/enic/enic_pp.c | 5 +++++
3 files changed, 13 insertions(+)
diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h
index 5ba5ad0..0b63227 100644
--- a/drivers/net/ethernet/cisco/enic/enic.h
+++ b/drivers/net/ethernet/cisco/enic/enic.h
@@ -88,6 +88,7 @@ struct enic_rx_coal {
#define ENIC_SET_NAME (1 << 2)
#define ENIC_SET_INSTANCE (1 << 3)
#define ENIC_SET_HOST (1 << 4)
+#define ENIC_SET_VMNAME (1 << 5)
struct enic_port_profile {
u32 set;
@@ -97,6 +98,7 @@ struct enic_port_profile {
u8 host_uuid[PORT_UUID_MAX];
u8 vf_mac[ETH_ALEN];
u8 mac_addr[ETH_ALEN];
+ char vmname[PORT_PROFILE_MAX];
};
/* enic_rfs_fltr_node - rfs filter node in hash table
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index 929bfe7..6c7cd1b 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -831,6 +831,12 @@ static int enic_set_vf_port(struct net_device *netdev, int vf,
nla_data(port[IFLA_PORT_HOST_UUID]), PORT_UUID_MAX);
}
+ if (port[IFLA_PORT_VMNAME]) {
+ pp->set |= ENIC_SET_VMNAME;
+ memcpy(pp->vmname,
+ nla_data(port[IFLA_PORT_VMNAME]), PORT_PROFILE_MAX);
+ }
+
if (vf == PORT_SELF_VF) {
/* Special case handling: mac came from IFLA_VF_MAC */
if (!is_zero_ether_addr(prev_pp.vf_mac))
diff --git a/drivers/net/ethernet/cisco/enic/enic_pp.c b/drivers/net/ethernet/cisco/enic/enic_pp.c
index e6a8319..c2b620f 100644
--- a/drivers/net/ethernet/cisco/enic/enic_pp.c
+++ b/drivers/net/ethernet/cisco/enic/enic_pp.c
@@ -128,6 +128,11 @@ static int enic_set_port_profile(struct enic *enic, int vf)
sizeof(uuid_str), uuid_str);
}
+ if (pp->set & ENIC_SET_VMNAME) {
+ VIC_PROVINFO_ADD_TLV(vp, VIC_GENERIC_PROV_TLV_CLIENT_NAME_STR,
+ sizeof(pp->vmname), pp->vmname);
+ }
+
VIC_PROVINFO_ADD_TLV(vp,
VIC_GENERIC_PROV_TLV_OS_TYPE,
sizeof(os_type), &os_type);
--
2.1.0
^ permalink raw reply related
* [PATCH net-next v2 1/2] if_link: add client name to port profile
From: Govindarajulu Varadarajan @ 2014-10-02 22:41 UTC (permalink / raw)
To: davem, netdev; +Cc: ssujith, benve, Govindarajulu Varadarajan
In-Reply-To: <1412289683-8278-1-git-send-email-_govind@gmx.com>
This patch adds client name to port profile.
This is used by netlink client to send the client name in port profile.
Signed-off-by: Govindarajulu Varadarajan <_govind@gmx.com>
---
include/uapi/linux/if_link.h | 1 +
net/core/rtnetlink.c | 2 ++
2 files changed, 3 insertions(+)
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 0bdb77e..6ae0b0b 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -512,6 +512,7 @@ enum {
IFLA_PORT_HOST_UUID, /* binary UUID */
IFLA_PORT_REQUEST, /* __u8 */
IFLA_PORT_RESPONSE, /* __u16, output only */
+ IFLA_PORT_VMNAME, /* vm-name used by port profile */
__IFLA_PORT_MAX,
};
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index a688268..116d647 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1238,6 +1238,8 @@ static const struct nla_policy ifla_port_policy[IFLA_PORT_MAX+1] = {
.len = PORT_UUID_MAX },
[IFLA_PORT_REQUEST] = { .type = NLA_U8, },
[IFLA_PORT_RESPONSE] = { .type = NLA_U16, },
+ [IFLA_PORT_VMNAME] = { .type = NLA_STRING,
+ .len = PORT_PROFILE_MAX },
};
static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
--
2.1.0
^ permalink raw reply related
* [PATCH net-next v2 0/2] enic: add support to send port-profile's client name to firmware
From: Govindarajulu Varadarajan @ 2014-10-02 22:41 UTC (permalink / raw)
To: davem, netdev; +Cc: ssujith, benve, Govindarajulu Varadarajan
Firmware has support for sending client name of the port profile to the switch
it's connected to.
This series adds client name to port profile which is sent to hardware while
associating a port profile to VF.
Since port profile are defined in switch, this patch makes it easier to check
what VM is using a port profile.
v2:
Split single patch to multiple patches. First patch adds client name to netlink
facility. Second patch adds driver support.
Govindarajulu Varadarajan (2):
if_link: add client name to port profile
enic: add vmname port-profile handler
drivers/net/ethernet/cisco/enic/enic.h | 2 ++
drivers/net/ethernet/cisco/enic/enic_main.c | 6 ++++++
drivers/net/ethernet/cisco/enic/enic_pp.c | 5 +++++
include/uapi/linux/if_link.h | 1 +
net/core/rtnetlink.c | 2 ++
5 files changed, 16 insertions(+)
--
2.1.0
^ permalink raw reply
* Re: macvlan: optimizing the receive path?
From: Stephen Hemminger @ 2014-10-02 21:31 UTC (permalink / raw)
To: Jason Baron; +Cc: netdev, kaber
In-Reply-To: <542DB55D.3090601@akamai.com>
On Thu, 02 Oct 2014 16:28:13 -0400
Jason Baron <jbaron@akamai.com> wrote:
> Hi,
>
> I was just wondering why the netif_rx(skb) call in macvlan_handle_frame()
> was necessary? IE:
It is to prevent too deep a call stack of
netif_receive_skb
macvlan_receive
netif_receive_skb ...
^ permalink raw reply
* Re: [RFC PATCH linux 2/2] fs/proc: use a hash table for the directory entries
From: Stephen Hemminger @ 2014-10-02 21:27 UTC (permalink / raw)
To: Eric W. Biederman
Cc: Alexey Dobriyan, Nicolas Dichtel, netdev, linux-kernel, davem,
akpm, rui.xiang, viro, oleg, gorcunov, kirill.shutemov,
grant.likely, tytso, Thierry Herbelot
In-Reply-To: <87h9zmji3q.fsf@x220.int.ebiederm.org>
On Thu, 02 Oct 2014 14:07:37 -0700
ebiederm@xmission.com (Eric W. Biederman) wrote:
> Alexey Dobriyan <adobriyan@gmail.com> writes:
>
> > On Thu, Oct 02, 2014 at 11:01:50AM -0700, Eric W. Biederman wrote:
> >> Nicolas Dichtel <nicolas.dichtel@6wind.com> writes:
> >>
> >> > From: Thierry Herbelot <thierry.herbelot@6wind.com>
> >> >
> >> > The current implementation for the directories in /proc is using a single
> >> > linked list. This is slow when handling directories with large numbers of
> >> > entries (eg netdevice-related entries when lots of tunnels are opened).
> >> >
> >> > This patch enables multiple linked lists. A hash based on the entry name is
> >> > used to select the linked list for one given entry.
> >> >
> >> > The speed creation of netdevices is faster as shorter linked lists must be
> >> > scanned when adding a new netdevice.
> >>
> >> Is the directory of primary concern /proc/net/dev/snmp6 ?
> >>
> >> Unless I have configured my networking stack weird by mistake that
> >> is the only directory under /proc/net that grows when we add an
> >> interface.
> >>
> >> I just want to make certain I am seeing the same things that you are
> >> seeing.
> >>
> >> I feel silly for overlooking this directory when the rest of the
> >> scalability work was done.
> >
> > Slowdown comes from "duplicate name" check:
> >
> > for (tmp = dir->subdir; tmp; tmp = tmp->next)
> > if (strcmp(tmp->name, dp->name) == 0) {
> > WARN(1, "proc_dir_entry '%s/%s' already registered\n",
> > dir->name, dp->name);
> > break;
> > }
> >
> > Removal can be made O(1) after switching to doubly-linked list.
>
> Yes. There is the however unfortunate fact that proc directories exist
> to be used. If we don't switch to a better data structure than a linked
> list the actual use will then opening of the files under
> /proc/net/dev/snmp6/ will become O(N^2). Which doesn't help much
> (assuming those files are good for something).
>
> If those files aren't actually useful we should just make registering
> them a config option. Deprecate them strongly and let only people who
> need extreme backwards compatibility enable them.
Net-snmp uses them (agent/mibgroup/mibII/kernel_linux.c)
^ permalink raw reply
* Re: [RFC PATCH linux 2/2] fs/proc: use a hash table for the directory entries
From: Eric W. Biederman @ 2014-10-02 21:07 UTC (permalink / raw)
To: Alexey Dobriyan
Cc: Nicolas Dichtel, netdev, linux-kernel, davem, akpm, rui.xiang,
viro, oleg, gorcunov, kirill.shutemov, grant.likely, tytso,
Thierry Herbelot
In-Reply-To: <20141002200639.GA3497@p183.telecom.by>
Alexey Dobriyan <adobriyan@gmail.com> writes:
> On Thu, Oct 02, 2014 at 11:01:50AM -0700, Eric W. Biederman wrote:
>> Nicolas Dichtel <nicolas.dichtel@6wind.com> writes:
>>
>> > From: Thierry Herbelot <thierry.herbelot@6wind.com>
>> >
>> > The current implementation for the directories in /proc is using a single
>> > linked list. This is slow when handling directories with large numbers of
>> > entries (eg netdevice-related entries when lots of tunnels are opened).
>> >
>> > This patch enables multiple linked lists. A hash based on the entry name is
>> > used to select the linked list for one given entry.
>> >
>> > The speed creation of netdevices is faster as shorter linked lists must be
>> > scanned when adding a new netdevice.
>>
>> Is the directory of primary concern /proc/net/dev/snmp6 ?
>>
>> Unless I have configured my networking stack weird by mistake that
>> is the only directory under /proc/net that grows when we add an
>> interface.
>>
>> I just want to make certain I am seeing the same things that you are
>> seeing.
>>
>> I feel silly for overlooking this directory when the rest of the
>> scalability work was done.
>
> Slowdown comes from "duplicate name" check:
>
> for (tmp = dir->subdir; tmp; tmp = tmp->next)
> if (strcmp(tmp->name, dp->name) == 0) {
> WARN(1, "proc_dir_entry '%s/%s' already registered\n",
> dir->name, dp->name);
> break;
> }
>
> Removal can be made O(1) after switching to doubly-linked list.
Yes. There is the however unfortunate fact that proc directories exist
to be used. If we don't switch to a better data structure than a linked
list the actual use will then opening of the files under
/proc/net/dev/snmp6/ will become O(N^2). Which doesn't help much
(assuming those files are good for something).
If those files aren't actually useful we should just make registering
them a config option. Deprecate them strongly and let only people who
need extreme backwards compatibility enable them.
Alexey do you know that those files aren't useful? Unless we know
otherwise we should make those files useful.
Eric
^ permalink raw reply
* Re: [PATCH net-next 0/2] sunvnet: Packet processing in non-interrupt context.
From: David Miller @ 2014-10-02 20:43 UTC (permalink / raw)
To: sowmini.varadhan; +Cc: raghuram.kothakota, netdev
In-Reply-To: <20141002201203.GA6001@oracle.com>
From: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Date: Thu, 2 Oct 2014 16:12:03 -0400
> The patch is attached to the end of this email.
There are an explosion of simplifications and optimizations
possilbe once you've done a NAPI conversion, which I haven't
seen you perform here in this patch.
For example, you can now move everything into software IRQ context,
just disable the VIO interrupt and unconditionally go into NAPI
context from the VIO event.
No more irqsave/irqrestore.
Then the TX path even can run mostly lockless, it just needs
to hold the VIO lock for a minute period of time. The caller
holds the xmit_lock of the network device to prevent re-entry
into the ->ndo_start_xmit() path.
Really, what you've done here as a NAPI conversion is just the
beginning.
^ permalink raw reply
* macvlan: optimizing the receive path?
From: Jason Baron @ 2014-10-02 20:28 UTC (permalink / raw)
To: netdev; +Cc: kaber
Hi,
I was just wondering why the netif_rx(skb) call in macvlan_handle_frame()
was necessary? IE:
macvlan_handle_frame()
{
........
skb->dev = dev;
skb->pkt_type = PACKET_HOST;
****>ret = netif_rx(skb);
out:
macvlan_count_rx(vlan, len, ret == NET_RX_SUCCESS, 0);
return RX_HANDLER_CONSUMED;
}
I think the point of going through netif_rx() is to ensure that we throttle
incoming packets, but hasn't that already been accomplished in this path?
That is if the packets are arriving from the physical NIC, we've already
throttled them by this point. Otherwise, if they are coming via
macvlan_queue_xmit(), it calls either 'dev_forward_skb()', which ends
up calling netif_rx_internal(), or else in broadcast mode there is
to be throttling via macvlan_broadcast_enqueue().
So I suspect there is a code path that I am missing but the netif_rx() call in
question essentially re-queues packets coming from off the box. I've tried the
simple patch below to optimize this path, and obviously performs a lot better
in my limited testing.
Thanks,
-Jason
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -321,8 +321,8 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
skb->dev = dev;
skb->pkt_type = PACKET_HOST;
- ret = netif_rx(skb);
-
+ macvlan_count_rx(vlan, len, true, 0);
+ return RX_HANDLER_ANOTHER;
out:
macvlan_count_rx(vlan, len, ret == NET_RX_SUCCESS, 0);
return RX_HANDLER_CONSUMED;
^ permalink raw reply
* Re: [PATCH net-next 0/2] sunvnet: Packet processing in non-interrupt context.
From: Sowmini Varadhan @ 2014-10-02 20:12 UTC (permalink / raw)
To: David Miller; +Cc: raghuram.kothakota, netdev
In-Reply-To: <20141001.162529.2246298941833907545.davem@davemloft.net>
On (10/01/14 16:25), David Miller wrote:
>
> The limit is by default 64 packets, it won't matter.
>
> I think you're overplaying the things that block use of NAPI, how
> about implementing it properly, using netif_gso_receive() and proper
> RCU accesses, and coming back with some real performance measurements?
I hope I did not give the impression that I've cut some corners and
did not do adequate testing to get here, because that is not the case.
I dont know what s/netif_skb_receive/napi_gro_receive has to do with it -
but I resurrected my napi prototype, caught up with Jumbo MTU patc,
and replaced netif_receive_skb with napi_gro_receive.
The patch is attached to the end of this email. "Real performance
measurements" are below.
Afaict, the patch is quite "proper" - I was following
http://www.linuxfoundation.org/collaborate/workgroups/networking/napi -
and the patch even goes to a lot of trouble to avoid sending needless
ldc messages arising from some napi-imposed budget. Here's the perf
data. Remember that packet size is 1500 bytes, so, e.g., 2 Gbps is approx
167k pps. Also the baseline perf today (without napi) is 1 - 1.3 Gbps.
budget iperf throughput
64 336 Mbps
128 556 Mbps
512 398 Mbps
If I over-budget to 2048, and force my vnet_poll() to lie by returning
`budget', I can get an iperf throughput of approx 2.2 - 2.3 Gbps
for 1500 byte packets i.e., 167k pps. Yes, I violate NAPI rules in doing
this, and from reading the code, this forces me to a non-polling,
pure-softirq mode. But this is also the best number I can get.
And as for mpstat output it comes out wit 100% of the softirqs on
2 cpus- something like this:
CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle
all 0.00 0.00 0.57 0.06 0.00 12.67 0.00 0.00 86.70
0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
4 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
6 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
7 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
8 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 99.00
9 0.00 0.00 0.00 0.00 0.00 100.00 0.00 0.00 0.00
10 0.00 0.00 1.98 0.00 0.00 0.00 0.00 0.00 98.02
11 0.00 0.00 0.99 0.00 0.00 0.00 0.00 0.00 99.01
12 0.00 0.00 0.00 0.00 0.00 100.00 0.00 0.00 0.00
13 0.00 0.00 3.00 0.00 0.00 0.00 0.00 0.00 97.00
14 0.00 0.00 2.56 0.00 0.00 0.00 0.00 0.00 97.44
15 0.00 0.00 1.00 1.00 0.00 0.00 0.00 0.00 98.00
Whereas with the workq, the load was spread nicely across multiple cpus.
I can share "Real performance data" for that as well, if you are curious.
Some differences between sunvnet-ldc and the typical network driver
that might be causing the perf drop here:
- The biggest benefit of NAPI is that it permits the reading of multiple
packets in the context of a single interrupt, but the ldc/sunvnet infra
already does that anyway. So the extra polling offered by NAPI does
not have a significant benefit for my test- I can just as easily
achieve load-spreading and fare-share in a non-interrupt context with
a workq/kthread?
- But the VDC driver is also different from the typical driver in the
"STOPPED" message- usually drivers only get signalled when the producer
publishes data, the consumer does not send any signal back to producer,
though the VDC driver does the latter. I've had to add more state-tracking
code to get around this.
Note that I am *not* attempting to fix the vnet race condition here-
that one is a pre-existing condition that I caught by merely reading
the code (I can easily look the other way), and my patch does not make
it worse. Let's discuss that one later.
NAPI Patch follows. Please tell me what's improper about it.
---------------------------------------------------------------------
diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c
index 1539672..da05d68 100644
--- a/drivers/net/ethernet/sun/sunvnet.c
+++ b/drivers/net/ethernet/sun/sunvnet.c
@@ -33,6 +33,9 @@
#define DRV_MODULE_VERSION "1.0"
#define DRV_MODULE_RELDATE "June 25, 2007"
+/* #define VNET_BUDGET 2048 */ /* see comments in vnet_poll() */
+#define VNET_BUDGET 64 /* typical budget */
+
static char version[] =
DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
@@ -274,6 +277,7 @@ static struct sk_buff *alloc_and_align_skb(struct net_device *dev,
return skb;
}
+/* reads in exactly one sk_buff */
static int vnet_rx_one(struct vnet_port *port, unsigned int len,
struct ldc_trans_cookie *cookies, int ncookies)
{
@@ -311,9 +315,7 @@ static int vnet_rx_one(struct vnet_port *port, unsigned int len,
dev->stats.rx_packets++;
dev->stats.rx_bytes += len;
-
- netif_rx(skb);
-
+ napi_gro_receive(&port->napi, skb);
return 0;
out_free_skb:
@@ -444,6 +446,7 @@ static int vnet_walk_rx_one(struct vnet_port *port,
desc->cookies[0].cookie_addr,
desc->cookies[0].cookie_size);
+ /* read in one packet */
err = vnet_rx_one(port, desc->size, desc->cookies, desc->ncookies);
if (err == -ECONNRESET)
return err;
@@ -456,10 +459,11 @@ static int vnet_walk_rx_one(struct vnet_port *port,
}
static int vnet_walk_rx(struct vnet_port *port, struct vio_dring_state *dr,
- u32 start, u32 end)
+ u32 start, u32 end, int *npkts, int budget)
{
struct vio_driver_state *vio = &port->vio;
int ack_start = -1, ack_end = -1;
+ int send_ack = 1;
end = (end == (u32) -1) ? prev_idx(start, dr) : next_idx(end, dr);
@@ -471,6 +475,7 @@ static int vnet_walk_rx(struct vnet_port *port, struct vio_dring_state *dr,
return err;
if (err != 0)
break;
+ (*npkts)++;
if (ack_start == -1)
ack_start = start;
ack_end = start;
@@ -482,13 +487,28 @@ static int vnet_walk_rx(struct vnet_port *port, struct vio_dring_state *dr,
return err;
ack_start = -1;
}
+ if ((*npkts) >= budget ) {
+ send_ack = 0;
+ break;
+ }
}
if (unlikely(ack_start == -1))
ack_start = ack_end = prev_idx(start, dr);
- return vnet_send_ack(port, dr, ack_start, ack_end, VIO_DRING_STOPPED);
+ if (send_ack) {
+ int ret;
+ port->napi_resume = false;
+ ret = vnet_send_ack(port, dr, ack_start, ack_end,
+ VIO_DRING_STOPPED);
+ return ret;
+ } else {
+ port->napi_resume = true;
+ port->napi_stop_idx = ack_end;
+ return (56);
+ }
}
-static int vnet_rx(struct vnet_port *port, void *msgbuf)
+static int vnet_rx(struct vnet_port *port, void *msgbuf, int *npkts,
+ int budget)
{
struct vio_dring_data *pkt = msgbuf;
struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_RX_RING];
@@ -505,11 +525,13 @@ static int vnet_rx(struct vnet_port *port, void *msgbuf)
return 0;
}
- dr->rcv_nxt++;
+ if (!port->napi_resume)
+ dr->rcv_nxt++;
/* XXX Validate pkt->start_idx and pkt->end_idx XXX */
- return vnet_walk_rx(port, dr, pkt->start_idx, pkt->end_idx);
+ return vnet_walk_rx(port, dr, pkt->start_idx, pkt->end_idx,
+ npkts, budget);
}
static int idx_is_pending(struct vio_dring_state *dr, u32 end)
@@ -534,7 +556,10 @@ static int vnet_ack(struct vnet_port *port, void *msgbuf)
struct net_device *dev;
struct vnet *vp;
u32 end;
+ unsigned long flags;
struct vio_net_desc *desc;
+ bool need_trigger = false;
+
if (unlikely(pkt->tag.stype_env != VIO_DRING_DATA))
return 0;
@@ -545,21 +570,17 @@ static int vnet_ack(struct vnet_port *port, void *msgbuf)
/* sync for race conditions with vnet_start_xmit() and tell xmit it
* is time to send a trigger.
*/
+ spin_lock_irqsave(&port->vio.lock, flags);
dr->cons = next_idx(end, dr);
desc = vio_dring_entry(dr, dr->cons);
- if (desc->hdr.state == VIO_DESC_READY && port->start_cons) {
- /* vnet_start_xmit() just populated this dring but missed
- * sending the "start" LDC message to the consumer.
- * Send a "start" trigger on its behalf.
- */
- if (__vnet_tx_trigger(port, dr->cons) > 0)
- port->start_cons = false;
- else
- port->start_cons = true;
- } else {
- port->start_cons = true;
- }
+ if (desc->hdr.state == VIO_DESC_READY && !port->start_cons)
+ need_trigger = true;
+ else
+ port->start_cons = true; /* vnet_start_xmit will send trigger */
+ spin_unlock_irqrestore(&port->vio.lock, flags);
+ if (need_trigger && __vnet_tx_trigger(port, dr->cons) <= 0)
+ port->start_cons = true;
vp = port->vp;
dev = vp->dev;
@@ -617,33 +638,12 @@ static void maybe_tx_wakeup(unsigned long param)
netif_tx_unlock(dev);
}
-static void vnet_event(void *arg, int event)
+static int vnet_event_napi(struct vnet_port *port, int budget)
{
- struct vnet_port *port = arg;
struct vio_driver_state *vio = &port->vio;
- unsigned long flags;
int tx_wakeup, err;
- spin_lock_irqsave(&vio->lock, flags);
-
- if (unlikely(event == LDC_EVENT_RESET ||
- event == LDC_EVENT_UP)) {
- vio_link_state_change(vio, event);
- spin_unlock_irqrestore(&vio->lock, flags);
-
- if (event == LDC_EVENT_RESET) {
- port->rmtu = 0;
- vio_port_up(vio);
- }
- return;
- }
-
- if (unlikely(event != LDC_EVENT_DATA_READY)) {
- pr_warn("Unexpected LDC event %d\n", event);
- spin_unlock_irqrestore(&vio->lock, flags);
- return;
- }
-
+ int npkts = 0;
tx_wakeup = err = 0;
while (1) {
union {
@@ -651,6 +651,20 @@ static void vnet_event(void *arg, int event)
u64 raw[8];
} msgbuf;
+ if (port->napi_resume) {
+ struct vio_dring_data *pkt =
+ (struct vio_dring_data *)&msgbuf;
+ struct vio_dring_state *dr =
+ &port->vio.drings[VIO_DRIVER_RX_RING];
+
+ pkt->tag.type = VIO_TYPE_DATA;
+ pkt->tag.stype = VIO_SUBTYPE_INFO;
+ pkt->tag.stype_env = VIO_DRING_DATA;
+ pkt->seq = dr->rcv_nxt;
+ pkt->start_idx = next_idx(port->napi_stop_idx, dr);
+ pkt->end_idx = -1;
+ goto napi_resume;
+ }
err = ldc_read(vio->lp, &msgbuf, sizeof(msgbuf));
if (unlikely(err < 0)) {
if (err == -ECONNRESET)
@@ -667,10 +681,12 @@ static void vnet_event(void *arg, int event)
err = vio_validate_sid(vio, &msgbuf.tag);
if (err < 0)
break;
-
+napi_resume:
if (likely(msgbuf.tag.type == VIO_TYPE_DATA)) {
if (msgbuf.tag.stype == VIO_SUBTYPE_INFO) {
- err = vnet_rx(port, &msgbuf);
+ err = vnet_rx(port, &msgbuf, &npkts, budget);
+ if (npkts >= budget || npkts == 0)
+ break;
} else if (msgbuf.tag.stype == VIO_SUBTYPE_ACK) {
err = vnet_ack(port, &msgbuf);
if (err > 0)
@@ -691,15 +707,54 @@ static void vnet_event(void *arg, int event)
if (err == -ECONNRESET)
break;
}
- spin_unlock(&vio->lock);
- /* Kick off a tasklet to wake the queue. We cannot call
- * maybe_tx_wakeup directly here because we could deadlock on
- * netif_tx_lock() with dev_watchdog()
- */
if (unlikely(tx_wakeup && err != -ECONNRESET))
tasklet_schedule(&port->vp->vnet_tx_wakeup);
+ return npkts;
+}
+static int vnet_poll(struct napi_struct *napi, int budget)
+{
+ struct vnet_port *port = container_of(napi, struct vnet_port, napi);
+ struct vio_driver_state *vio = &port->vio;
+ int processed = vnet_event_napi(port, budget);
+
+ if (processed < budget) {
+ napi_complete(napi);
+ napi_reschedule(napi);
+ vio_set_intr(vio->vdev->rx_ino, HV_INTR_ENABLED);
+ }
+ /* return budget; */ /* liar! but better throughput! */
+ return processed;
+}
+
+static void vnet_event(void *arg, int event)
+{
+ struct vnet_port *port = arg;
+ struct vio_driver_state *vio = &port->vio;
+ unsigned long flags;
+
+ spin_lock_irqsave(&vio->lock, flags);
+
+ if (unlikely(event == LDC_EVENT_RESET ||
+ event == LDC_EVENT_UP)) {
+ vio_link_state_change(vio, event);
+ spin_unlock_irqrestore(&vio->lock, flags);
+
+ if (event == LDC_EVENT_RESET)
+ vio_port_up(vio);
+ return;
+ }
+
+ if (unlikely(event != LDC_EVENT_DATA_READY)) {
+ pr_warning("Unexpected LDC event %d\n", event);
+ spin_unlock_irqrestore(&vio->lock, flags);
+ return;
+ }
+
+ spin_unlock(&vio->lock);
local_irq_restore(flags);
+ vio_set_intr(vio->vdev->rx_ino, HV_INTR_DISABLED);
+ napi_schedule(&port->napi);
}
static int __vnet_tx_trigger(struct vnet_port *port, u32 start)
@@ -1342,6 +1397,22 @@ err_out:
return err;
}
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void vnet_poll_controller(struct net_device *dev)
+{
+ struct vnet *vp = netdev_priv(dev);
+ struct vnet_port *port;
+ unsigned long flags;
+
+ spin_lock_irqsave(&vp->lock, flags);
+ if (!list_empty(&vp->port_list)) {
+ port = list_entry(vp->port_list.next, struct vnet_port, list);
+ napi_schedule(&port->napi);
+ }
+ spin_unlock_irqrestore(&vp->lock, flags);
+
+}
+#endif
static LIST_HEAD(vnet_list);
static DEFINE_MUTEX(vnet_list_mutex);
@@ -1354,6 +1425,9 @@ static const struct net_device_ops vnet_ops = {
.ndo_tx_timeout = vnet_tx_timeout,
.ndo_change_mtu = vnet_change_mtu,
.ndo_start_xmit = vnet_start_xmit,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = vnet_poll_controller,
+#endif
};
static struct vnet *vnet_new(const u64 *local_mac)
@@ -1536,6 +1610,9 @@ static int vnet_port_probe(struct vio_dev *vdev, const struct vio_device_id *id)
if (err)
goto err_out_free_port;
+ netif_napi_add(port->vp->dev, &port->napi, vnet_poll, VNET_BUDGET);
+ napi_enable(&port->napi);
+
err = vnet_port_alloc_tx_bufs(port);
if (err)
goto err_out_free_ldc;
@@ -1592,6 +1669,8 @@ static int vnet_port_remove(struct vio_dev *vdev)
del_timer_sync(&port->vio.timer);
del_timer_sync(&port->clean_timer);
+ napi_disable(&port->napi);
+
spin_lock_irqsave(&vp->lock, flags);
list_del(&port->list);
hlist_del(&port->hash);
hlist_del(&port->hash);
diff --git a/drivers/net/ethernet/sun/sunvnet.h b/drivers/net/ethernet/sun/sunvnet.h
index c911045..3c745d0 100644
--- a/drivers/net/ethernet/sun/sunvnet.h
+++ b/drivers/net/ethernet/sun/sunvnet.h
@@ -56,6 +56,10 @@ struct vnet_port {
struct timer_list clean_timer;
u64 rmtu;
+
+ struct napi_struct napi;
+ u32 napi_stop_idx;
+ bool napi_resume;
};
static inline struct vnet_port *to_vnet_port(struct vio_driver_state *vio)
^ permalink raw reply related
* Re: [PATCH net-next] net: better IFF_XMIT_DST_RELEASE support
From: Eric Dumazet @ 2014-10-02 20:06 UTC (permalink / raw)
To: Julian Anastasov; +Cc: David Miller, netdev
In-Reply-To: <alpine.LFD.2.11.1410022231100.3225@ja.home.ssi.bg>
On Thu, 2014-10-02 at 22:34 +0300, Julian Anastasov wrote:
> Hello,
>
> On Thu, 2 Oct 2014, Eric Dumazet wrote:
>
> > From: Eric Dumazet <edumazet@google.com>
> >
> > Testing xmit_more support with netperf and connected UDP sockets,
> > I found strange dst refcount false sharing.
> >
> > Current handling of IFF_XMIT_DST_RELEASE is not optimal.
> >
> > dropping dst in validate_xmit_skb() is certainly too late in case
> > packet was queued by cpu X but dequeued by cpu Y
> >
> > The logical point to take care of drop/force is in __dev_queue_xmit()
> > before even taking qdisc lock.
>
> Does it hurt skb_dst usage in net/sched/, for example,
> dst->tclassid in net/sched/cls_route.c ?
Hmm good point...
Then, if a qdisc like that is used, I guess we can remove
IFF_XMIT_DST_RELEASE from dev->priv_flags
Maybe I should add a dev->dst_are_needed counter, instead using a flag.
Thanks
^ permalink raw reply
* Re: [RFC PATCH linux 2/2] fs/proc: use a hash table for the directory entries
From: Alexey Dobriyan @ 2014-10-02 20:06 UTC (permalink / raw)
To: Eric W. Biederman
Cc: Nicolas Dichtel, netdev, linux-kernel, davem, akpm, rui.xiang,
viro, oleg, gorcunov, kirill.shutemov, grant.likely, tytso,
Thierry Herbelot
In-Reply-To: <87h9zmpcz5.fsf@x220.int.ebiederm.org>
On Thu, Oct 02, 2014 at 11:01:50AM -0700, Eric W. Biederman wrote:
> Nicolas Dichtel <nicolas.dichtel@6wind.com> writes:
>
> > From: Thierry Herbelot <thierry.herbelot@6wind.com>
> >
> > The current implementation for the directories in /proc is using a single
> > linked list. This is slow when handling directories with large numbers of
> > entries (eg netdevice-related entries when lots of tunnels are opened).
> >
> > This patch enables multiple linked lists. A hash based on the entry name is
> > used to select the linked list for one given entry.
> >
> > The speed creation of netdevices is faster as shorter linked lists must be
> > scanned when adding a new netdevice.
>
> Is the directory of primary concern /proc/net/dev/snmp6 ?
>
> Unless I have configured my networking stack weird by mistake that
> is the only directory under /proc/net that grows when we add an
> interface.
>
> I just want to make certain I am seeing the same things that you are
> seeing.
>
> I feel silly for overlooking this directory when the rest of the
> scalability work was done.
Slowdown comes from "duplicate name" check:
for (tmp = dir->subdir; tmp; tmp = tmp->next)
if (strcmp(tmp->name, dp->name) == 0) {
WARN(1, "proc_dir_entry '%s/%s' already registered\n",
dir->name, dp->name);
break;
}
Removal can be made O(1) after switching to doubly-linked list.
Alexey
^ permalink raw reply
* Re: [PATCH v1 5/5] driver-core: add driver asynchronous probe support
From: Luis R. Rodriguez @ 2014-10-02 20:06 UTC (permalink / raw)
To: Tom Gundersen, systemd-devel
Cc: One Thousand Gnomes, Takashi Iwai, Kay Sievers, pmladek, LKML,
Michal Hocko, Praveen Krishnamoorthy, hare, Nagalakshmi Nandigama,
werner, Tetsuo Handa, mpt-fusionlinux.pdl, Tim Gardner,
Benjamin Poirier, Santosh Rastapur, Casey Leedom, Hariprasad S,
Pierre Fersing, dbueso, Sreekanth Reddy, Arjan van de Ven,
Abhijit Mahajan, Linux SCSI List <linu
In-Reply-To: <CAG-2HqVBnXUKSRBrJE=gEKA3St5KMfdgAbx2vRfpF3qw_teLOg@mail.gmail.com>
As per Tom, adding systemd-devel for advice / review / of the request to avoid
the sigkill for kmod workers. Keeping others on Cc as its a discussion that
I think can help if both camps are involved. Specially since we've been
ping ponging back and forth on this particular topic for a long time now.
On Thu, Oct 02, 2014 at 08:12:37AM +0200, Tom Gundersen wrote:
> On Tue, Sep 30, 2014 at 5:24 PM, Luis R. Rodriguez <mcgrof@suse.com> wrote:
> >> > commit e64fae5573e566ce4fd9b23c68ac8f3096603314
> >> > Author: Kay Sievers <kay.sievers@vrfy.org>
> >> > Date: Wed Jan 18 05:06:18 2012 +0100
> >> >
> >> > udevd: kill hanging event processes after 30 seconds
> >> >
> >> > Some broken kernel drivers load firmware synchronously in the module init
> >> > path and block modprobe until the firmware request is fulfilled.
> >> > <...>
> >>
> >> This was a workaround to avoid a deadlock between udev and the kernel.
> >> The 180 s timeout was already in place before this change, and was not
> >> motivated by firmware loading. Also note that this patch was not about
> >> "tracking device drivers", just about avoiding dead-lock.
> >
> > Thanks, can you elaborate on how a deadlock can occur if the kmod
> > worker is not at some point sigkilled?
>
> This was only relevant whet udev did the firmware loading. modprobe
> would wait for the kernel, which would wait for the firmware loading,
> which would wait for modprobe. This is no longer a problem as udev
> does not do firmware loading any more.
Thanks for clarifying. So the deadlock concern is no longer there, therefore
it is not a reason to keep the sigkill for kmod.
> > Is the issue that if there is no extra worker available and all are
> > idling on sleep / synchronous long work boot will potentially hang
> > unless a new worker becomes available to do more work?
>
> Correct.
Ok.
> > If so I can
> > see the sigkill helping for hanging tasks but it doesn't necessarily
> > mean its a good idea to kill modules loading taking a while. Also
> > what if the sigkill is just avoided for *just* kmod workers?
>
> Depending on the number of devices you have, I suppose we could still
> exhaust the workers.
Ok can systemd dynamically create a worker or set of workers per device
that creeps up? Async probe for most drivers will help with this but
having it dynamic should help as well, specially since there are drivers
that will require probe synchronously -- and the fact that async probe
mechanism is not yet merged.
> >> The way I see it, the current status from systemd's side is: our
> >> short-term work-around is to increase the timeout, and at the moment
> >> it appears no long-term solution is needed (i.e., it seems like the
> >> right thing to do is to make sure insmod can be near instantaneous, it
> >> appears people are working towards this goal, and so far no examples
> >> have cropped up showing that it is fundamentally impossible (once/if
> >> they do, we should of course revisit the problem)).
> >
> > That again would be reactive behaviour, what would prevent avoiding the
> > sigkill only for kmod workers? Is it known the deadlock is immiment?
> > If the amount of workers for kmod that would hit the timeout is
> > considered low I don't see how that's possible and why not just lift
> > the sigkill.
>
> Making kmod a special case is of course possible. However, as long as
> there is no fundamental reason why kmod should get this special
> treatment, this just looks like a work-around to me.
I've mentioned a series of five reasons why its a bad idea right now to
sigkill modules [0], we're reviewed them each and still at least
items 2-4 remain particularly valid fundamental reasons to avoid it
specially if the deadlock is no longer possible. Running out of
workers because they are loading modules and that is taking a while
is not really a good standing reason to be killing them, specially
if the timeout already is set to a high value. All we're doing there is
limiting Linux / number of devices arbitrarily just to help free
workers, and it seems that should be dealt with differently. Killing
module loading arbitrarily in the middle is not advisable and can cause
more issue than help in any way.
Async probe mechanism will help free workers faster but this patch series is
still being evolved, we should still address the sigkill for kmod workers
separately and see what remaining reasons we have for it in light of the
possible issues highlighted that it can introduce if kept. If we want to
capture drivers taking long on probe each subsystem should handle that and WARN
/ pick up on it, we cannot however assume that this a generally bad things as
discussed before. We will also not be able to async probe *every* driver,
which is why the series allows a flag to specify for this.
[0] https://lkml.org/lkml/2014/9/26/879
> We already have a
> work-around, which is to increase the global timeout. If you still
> think we should do something different in systemd, it is probably best
> to take the discussion to systemd-devel to make sure all the relevant
> people are involved.
Sure, I've included systemd-devel. Hope is we can have a constructive
discussion on the sigkill for kmod.
Luis
^ permalink raw reply
* Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns
From: Andy Lutomirski @ 2014-10-02 19:48 UTC (permalink / raw)
To: Eric W. Biederman
Cc: Andrew Morton, Network Development, Linux Containers,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Stephen Hemminger, Cong Wang, Linux API, Nicolas Dichtel,
David S. Miller
In-Reply-To: <877g0il0gd.fsf-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
On Thu, Oct 2, 2014 at 12:45 PM, Eric W. Biederman
<ebiederm@xmission.com> wrote:
> Andy Lutomirski <luto@amacapital.net> writes:
>
>> On Thu, Oct 2, 2014 at 12:20 PM, Eric W. Biederman
>> <ebiederm@xmission.com> wrote:
>>> Nicolas Dichtel <nicolas.dichtel@6wind.com> writes:
>>>
>>>> Le 29/09/2014 20:43, Eric W. Biederman a écrit :
>>>>> Nicolas Dichtel <nicolas.dichtel@6wind.com> writes:
>>>>>
>>>>>> Le 26/09/2014 20:57, Eric W. Biederman a écrit :
>>>>>>> Andy Lutomirski <luto@amacapital.net> writes:
>>>>>>>
>>>>>>>> On Fri, Sep 26, 2014 at 11:10 AM, Eric W. Biederman
>>>>>>>> <ebiederm@xmission.com> wrote:
>>>>>>>>> I see two ways to go with this.
>>>>>>>>>
>>>>>>>>> - A per network namespace table to that you can store ids for ``peer''
>>>>>>>>> network namespaces. The table would need to be populated manually by
>>>>>>>>> the likes of ip netns add.
>>>>>>>>>
>>>>>>>>> That flips the order of assignment and makes this idea solid.
>>>>>> I have a preference for this solution, because it allows to have a full
>>>>>> broadcast messages. When you have a lot of network interfaces (> 10k),
>>>>>> it saves a lot of time to avoid another request to get all informations.
>>>>>
>>>>> My practical question is how often does it happen that we care?
>>>> In fact, I don't think that scenarii with a lot of netns have a full mesh of
>>>> x-netns interfaces. It will be more one "link" netns with the physical
>>>> interface and all other with one interface with the link part in this "link"
>>>> netns. Hence, only one nsid is needing in each netns.
>>>
>>> I will buy that a full mesh is unlikely.
>>>
>>> For people doing simulations anything physical has a limited number of
>>> links.
>>>
>>> For people wanting all to all connectivity setting up an internal
>>> macvlan (or the equivalent) is likely much simpler and more efficient
>>> that a full mesh.
>>>
>>> So the question in my mind is how do we create these identifiers at need
>>> (when we create the cross network namespace links) instead of at network
>>> namespace creation time. I don't see an answer to that in your patches,
>>> and perhaps it obvious.
>>>
>>
>> I wonder whether part of the problem is that we're thinking about
>> scoping wrong. What if we made the hierarchy more explicit?
>>
>> For example, we could give each netns an admin-assigned identifier
>> (e.g. a 64-bit number, maybe required to be unique, maybe not)
>> relative to its containing userns. Then we could come up with a way
>> to identify user namespaces (i.e. inode number relative to containing
>> user ns, if that's well-defined).
>
> If as suggested we only assign ids when a tunnel (or equivalent) is
> created between two network namespaces the space cost is a non-issue.
> The ids become at worst a constant factor addition to the cost of the
> tunnel.
>
> To keep things simple we may want to assign a free id (if one does not
> exist) when we connect a tunnel to a network namespace.
>
>> From user code's perspective, netnses that are in the requester's
>> userns or its descendents are identified by a path through a (possibly
>> zero-length) sequence of userns ids followed by a netns id. Netnses
>> outside the requester's userns hierarchy cannot be named at all.
>>
>> Would this make sense?
>
> Nope. What happens if I migrate 2 of the 4 network namespaces in a user
> namespace? The migration potentially fails. Application migration does
> not require user namespace migration.
Hmm. I guess that, as long as those network namespaces aren't
connected to anything else, migrating like that makes sense and ought
to work. Fair enough.
--Andy
_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/containers
^ permalink raw reply
* Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns
From: Eric W. Biederman @ 2014-10-02 19:45 UTC (permalink / raw)
To: Andy Lutomirski
Cc: Andrew Morton, Network Development, Linux Containers,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Stephen Hemminger, Cong Wang, Linux API, Nicolas Dichtel,
David S. Miller
In-Reply-To: <CALCETrWxqzUF1x+TmW5G4kuHPP+sUtiRaT6dpZ0mQTJ217QB5w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Andy Lutomirski <luto@amacapital.net> writes:
> On Thu, Oct 2, 2014 at 12:20 PM, Eric W. Biederman
> <ebiederm@xmission.com> wrote:
>> Nicolas Dichtel <nicolas.dichtel@6wind.com> writes:
>>
>>> Le 29/09/2014 20:43, Eric W. Biederman a écrit :
>>>> Nicolas Dichtel <nicolas.dichtel@6wind.com> writes:
>>>>
>>>>> Le 26/09/2014 20:57, Eric W. Biederman a écrit :
>>>>>> Andy Lutomirski <luto@amacapital.net> writes:
>>>>>>
>>>>>>> On Fri, Sep 26, 2014 at 11:10 AM, Eric W. Biederman
>>>>>>> <ebiederm@xmission.com> wrote:
>>>>>>>> I see two ways to go with this.
>>>>>>>>
>>>>>>>> - A per network namespace table to that you can store ids for ``peer''
>>>>>>>> network namespaces. The table would need to be populated manually by
>>>>>>>> the likes of ip netns add.
>>>>>>>>
>>>>>>>> That flips the order of assignment and makes this idea solid.
>>>>> I have a preference for this solution, because it allows to have a full
>>>>> broadcast messages. When you have a lot of network interfaces (> 10k),
>>>>> it saves a lot of time to avoid another request to get all informations.
>>>>
>>>> My practical question is how often does it happen that we care?
>>> In fact, I don't think that scenarii with a lot of netns have a full mesh of
>>> x-netns interfaces. It will be more one "link" netns with the physical
>>> interface and all other with one interface with the link part in this "link"
>>> netns. Hence, only one nsid is needing in each netns.
>>
>> I will buy that a full mesh is unlikely.
>>
>> For people doing simulations anything physical has a limited number of
>> links.
>>
>> For people wanting all to all connectivity setting up an internal
>> macvlan (or the equivalent) is likely much simpler and more efficient
>> that a full mesh.
>>
>> So the question in my mind is how do we create these identifiers at need
>> (when we create the cross network namespace links) instead of at network
>> namespace creation time. I don't see an answer to that in your patches,
>> and perhaps it obvious.
>>
>
> I wonder whether part of the problem is that we're thinking about
> scoping wrong. What if we made the hierarchy more explicit?
>
> For example, we could give each netns an admin-assigned identifier
> (e.g. a 64-bit number, maybe required to be unique, maybe not)
> relative to its containing userns. Then we could come up with a way
> to identify user namespaces (i.e. inode number relative to containing
> user ns, if that's well-defined).
If as suggested we only assign ids when a tunnel (or equivalent) is
created between two network namespaces the space cost is a non-issue.
The ids become at worst a constant factor addition to the cost of the
tunnel.
To keep things simple we may want to assign a free id (if one does not
exist) when we connect a tunnel to a network namespace.
> From user code's perspective, netnses that are in the requester's
> userns or its descendents are identified by a path through a (possibly
> zero-length) sequence of userns ids followed by a netns id. Netnses
> outside the requester's userns hierarchy cannot be named at all.
>
> Would this make sense?
Nope. What happens if I migrate 2 of the 4 network namespaces in a user
namespace? The migration potentially fails. Application migration does
not require user namespace migration.
Eric
_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/containers
^ permalink raw reply
* HELLO BELOVED IN CHRIST PLEASE I NEED YOUR HELP
From: FROM MRS GRACE MANDA @ 2014-10-02 19:31 UTC (permalink / raw)
In-Reply-To: <92064508.199599.1412278051104.JavaMail.yahoo@jws100135.mail.ne1.yahoo.com>
[-- Attachment #1: Type: text/plain, Size: 54 bytes --]
KINDLY VIEW THE ATTACHED FILE AND GET BACK TO ME
[-- Attachment #2: FROM MRS GRACE MANDA.rtf --]
[-- Type: application/msword, Size: 42406 bytes --]
^ permalink raw reply
* Re: [PATCH net-next] net: better IFF_XMIT_DST_RELEASE support
From: Julian Anastasov @ 2014-10-02 19:34 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev
In-Reply-To: <1412267647.22242.3.camel@edumazet-glaptop2.roam.corp.google.com>
Hello,
On Thu, 2 Oct 2014, Eric Dumazet wrote:
> From: Eric Dumazet <edumazet@google.com>
>
> Testing xmit_more support with netperf and connected UDP sockets,
> I found strange dst refcount false sharing.
>
> Current handling of IFF_XMIT_DST_RELEASE is not optimal.
>
> dropping dst in validate_xmit_skb() is certainly too late in case
> packet was queued by cpu X but dequeued by cpu Y
>
> The logical point to take care of drop/force is in __dev_queue_xmit()
> before even taking qdisc lock.
Does it hurt skb_dst usage in net/sched/, for example,
dst->tclassid in net/sched/cls_route.c ?
> @@ -2895,6 +2887,14 @@ static int __dev_queue_xmit(struct sk_buff *skb, void *accel_priv)
>
> skb_update_prio(skb);
>
> + /* If device doesn't need skb->dst, release it right now while
> + * its hot in this cpu cache
> + */
> + if (dev->priv_flags & IFF_XMIT_DST_RELEASE)
> + skb_dst_drop(skb);
> + else
> + skb_dst_force(skb);
> +
> txq = netdev_pick_tx(dev, skb, accel_priv);
> q = rcu_dereference_bh(txq->qdisc);
Regards
--
Julian Anastasov <ja@ssi.bg>
^ permalink raw reply
* Re: [RFC PATCH net-next v3 1/4] netns: add genl cmd to add and get peer netns ids
From: Eric W. Biederman @ 2014-10-02 19:33 UTC (permalink / raw)
To: Nicolas Dichtel
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, luto-kltTT9wpgjJwATOyAt5JVQ,
stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ,
cwang-xCSkyg8dI+0RB7SZvlqPiA, linux-api-u79uwXL29TY76Z2rM5mHXA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <1412257690-31253-2-git-send-email-nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w@public.gmane.org>
Nicolas Dichtel <nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w@public.gmane.org> writes:
> With this patch, a user can define an id for a peer netns by providing a FD or a
> PID. These ids are local to netns (ie valid only into one netns).
>
> This will be useful for netlink messages when a x-netns interface is
> dumped.
You have a "id -> struct net *" table but you don't have a
"struct net * -> id" table which looks like it will impact the
performance of peernet2id at scale.
Eric
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox