Netdev List
 help / color / mirror / Atom feed
* [RFC][PATCHES] iov_iter.c rewrite
From: Al Viro @ 2014-12-04 20:20 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel, netdev

	First of all, I want to apologize for the nastiness of preprocessor
use in this series.  Seeing that the whole "macros that look like new kinds
of C statements" thing (including list_for_each_...(), etc) is very much not
to my liking, I really don't trust my taste on finer details and I'd very
much like some feedback.

	The reason for doing that kind of tricks is that iov_iter.c keeps
growing more and more boilerplate code.  For iov_iter-net series we need
	* csum_and_copy_from_iter()
	* csum_and_copy_to_iter()
	* copy_from_iter_nocache()
That's 3 new primitives, each in 2 variants (iovec and bvec).
	* ITER_KVEC handled without going through uaccess.h stuff (and
independent of set_fs() state).
And *that* means 3 variants intstead of 2 for most of the existing primitives.
That's far too much, and the amount of copies of the same logics would pretty
much guarantee that it will be a breeding ground for hard-to-kill bugs.

	The following series (also in vfs.git#iov_iter) actually manages to
do all of the above *and* shrink the damn thing quite a bit.  The generated
code appears to be no worse than before.  The price is a couple of iterator
macros - iterate_all_kinds() and iterate_and_advance().  They are given an
iov_iter, size (i.e. the amount of data in iov_iter beginning we want to go
through), name of the loop variable and 3 variants of loop body - for iovec,
bvec and kvec resp.  Loop variable is declared *inside* the expansion of those
suckers according to the kind of iov_iter - it's struct iovec, struct bio_vec
or struct kvec, covering the current range to deal with.
	The difference between those two is that iterate_and_advance() will
advance the iov_iter by the amount it has handled and iterate_all_kinds()
will leave iov_iter unchanged.

	Unless I hear anybody yelling, it goes into vfs.git#for-next today,
so if you have objections, suggestions, etc., give those *now*.

Al Viro (13):
      iov_iter.c: macros for iterating over iov_iter
      iov_iter.c: iterate_and_advance
      iov_iter.c: convert iov_iter_npages() to iterate_all_kinds
      iov_iter.c: convert iov_iter_get_pages() to iterate_all_kinds
      iov_iter.c: convert iov_iter_get_pages_alloc() to iterate_all_kinds
      iov_iter.c: convert iov_iter_zero() to iterate_and_advance
      iov_iter.c: get rid of bvec_copy_page_{to,from}_iter()
      iov_iter.c: convert copy_from_iter() to iterate_and_advance
      iov_iter.c: convert copy_to_iter() to iterate_and_advance
      iov_iter.c: handle ITER_KVEC directly
      csum_and_copy_..._iter()
      new helper: iov_iter_kvec()
      copy_from_iter_nocache()

Diffstat:
 include/linux/uio.h |    6 +
 mm/iov_iter.c       | 1077 +++++++++++++++++++++------------------------------
 2 files changed, 445 insertions(+), 638 deletions(-)

^ permalink raw reply

* Re: [PATCHv3 net] i40e: Implement ndo_gso_check()
From: Tom Herbert @ 2014-12-04 20:17 UTC (permalink / raw)
  To: Joe Stringer
  Cc: Linux Netdev List, LKML, Jesse Gross, Shannon Nelson,
	Brandeburg, Jesse, Jeff Kirsher, linux.nics
In-Reply-To: <1417718366-14310-1-git-send-email-joestringer@nicira.com>

On Thu, Dec 4, 2014 at 10:39 AM, Joe Stringer <joestringer@nicira.com> wrote:
> ndo_gso_check() was recently introduced to allow NICs to report the
> offloading support that they have on a per-skb basis. Add an
> implementation for this driver which checks for IPIP, GRE, UDP tunnels.
>
> Signed-off-by: Joe Stringer <joestringer@nicira.com>
> ---
> v3: Drop IPIP and GRE (no driver support even though hw supports it).
>     Check for UDP outer protocol for UDP tunnels.
> v2: Expand to include IP in IP and IPv4/IPv6 inside GRE/UDP tunnels.
>     Add MAX_INNER_LENGTH (as 80).
> ---
>  drivers/net/ethernet/intel/i40e/i40e_main.c |   26 ++++++++++++++++++++++++++
>  1 file changed, 26 insertions(+)
>
> diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
> index c3a7f4a..0d6493a 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_main.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
> @@ -7447,6 +7447,31 @@ static int i40e_ndo_fdb_dump(struct sk_buff *skb,
>
>  #endif /* USE_DEFAULT_FDB_DEL_DUMP */
>  #endif /* HAVE_FDB_OPS */
> +static bool i40e_gso_check(struct sk_buff *skb, struct net_device *dev)
> +{
> +       if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL) {
> +               unsigned char *ihdr;
> +
> +               if (skb->protocol != IPPROTO_UDP ||
> +                   skb->inner_protocol_type != ENCAP_TYPE_ETHER)
> +                       return false;
> +
> +               if (skb->inner_protocol == htons(ETH_P_TEB))
> +                       ihdr = skb_inner_mac_header(skb);
> +               else if (skb->inner_protocol == htons(ETH_P_IP) ||
> +                        skb->inner_protocol == htons(ETH_P_IPV6))
> +                       ihdr = skb_inner_network_header(skb);
> +               else
> +                       return false;
> +

Wow, this is getting complicated! :-( It's not clear that the protocol
specific checks are needed here since it looks like the header length
is being passed to the device later on. Also, I think we need
skb_inner_mac_header(skb) - skb_transport_header(skb) to always work
to give the length of the encapsulation headers (in case there is no
real inner mac header, then that offset should be for the network
header).

So would a simple check like this work:

if (skb->encapsulation &&
    (skb_inner_mac_header(skb) - skb_transport_header(skb)) >
MAX_TUNNEL_HDR_LEN)
       return false;

> +#define MAX_TUNNEL_HDR_LEN     80
> +               if (ihdr - skb_transport_header(skb) > MAX_TUNNEL_HDR_LEN)
> +                       return false;
> +       }
> +
> +       return true;
> +}
> +
>  static const struct net_device_ops i40e_netdev_ops = {
>         .ndo_open               = i40e_open,
>         .ndo_stop               = i40e_close,
> @@ -7487,6 +7512,7 @@ static const struct net_device_ops i40e_netdev_ops = {
>         .ndo_fdb_dump           = i40e_ndo_fdb_dump,
>  #endif
>  #endif
> +       .ndo_gso_check          = i40e_gso_check,
>  };
>
>  /**
> --
> 1.7.10.4
>

^ permalink raw reply

* Re: [patch iproute2 1/6] iproute2: ipa: show switch id
From: Eric W. Biederman @ 2014-12-04 20:06 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: netdev, davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse,
	pshelar, azhou, ben, stephen, jeffrey.t.kirsher, vyasevic,
	xiyou.wangcong, john.r.fastabend, edumazet, jhs, sfeldma,
	f.fainelli, roopa, linville, jasowang, nicolas.dichtel,
	ryazanov.s.a, buytenh, aviadr, nbd, alexei.starovoitov,
	Neil.Jerram, ronye, simon.horman, alexander.h.duyck, john.ronciak,
	mleitner, shrijeet, gospo, bcrl, hemal
In-Reply-To: <87wq672p49.fsf@x220.int.ebiederm.org>

ebiederm@xmission.com (Eric W. Biederman) writes:

> Jiri Pirko <jiri@resnulli.us> writes:
>
>>>So this id needs to be globally unique?
>>
>> No. It is enough to be unique within a single system. It serves for no
>> more than to find out 2 ids are same or not, no other info value.
>>
>> So when the drivers uses sane ids (like mac for example, or in case of
>> rocker an id which is passed by qemu command line), the chances of
>> collision are very very close to none (never say never).

Thinking about what you said a little more.

Two different sources of persistent numbers picking numbers by
completely different algorithms can give you no assurance that you don't
produce conflicts.

The switch id as desisgned can not work.

There are expected to be between 2**36 to 2**40 devices in this world.
Your first switch id is a 64it number.  At the very best by the birthday
pardox predicts there will be a conflict ever 2**32 devices or between
2**4 and 2**8 devices in the world with conflicts.  If the ids are not
randomly distributed (which they won't be) things could easily be much
much worse.

That is just good enough the code could get out there and run for years
before you have the nightmare of having to fix all of userspace.   That
is a nightmare no one needs.

So please remove this broken code, and this broken concept from the
kernel and go back to the drawing board.

Eric

^ permalink raw reply

* Re: [patch iproute2 1/6] iproute2: ipa: show switch id
From: Jiri Pirko @ 2014-12-04 19:54 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: netdev, davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse,
	pshelar, azhou, ben, stephen, jeffrey.t.kirsher, vyasevic,
	xiyou.wangcong, john.r.fastabend, edumazet, jhs, sfeldma,
	f.fainelli, roopa, linville, jasowang, nicolas.dichtel,
	ryazanov.s.a, buytenh, aviadr, nbd, alexei.starovoitov,
	Neil.Jerram, ronye, simon.horman, alexander.h.duyck, john.ronciak,
	mleitner, shrijeet, gospo, bcrl, hemal
In-Reply-To: <87wq672p49.fsf@x220.int.ebiederm.org>

Thu, Dec 04, 2014 at 08:26:14PM CET, ebiederm@xmission.com wrote:
>Jiri Pirko <jiri@resnulli.us> writes:
>
>>>So this id needs to be globally unique?
>>
>> No. It is enough to be unique within a single system. It serves for no
>> more than to find out 2 ids are same or not, no other info value.
>>
>> So when the drivers uses sane ids (like mac for example, or in case of
>> rocker an id which is passed by qemu command line), the chances of
>> collision are very very close to none (never say never).
>
>So the switch id isn't necessarily even as good as a manufacturers
>serial number that changes between different models, and anyone who uses
>this id must look at the driver to get uniqueness.
>
>Yes what is needed in the comparison to get uniqueness in a single
>system badly needs to be documented because that switch id is very much
>not enough on it's own.
>
>phys_port_id on the other hand is globally unique.  So please stop
>saying that this is anything like phys_port_id.

I'm sorry. But is is the same. And the purpose is very similar. In case
of phys port id to find out if 2 netdevices share the same physical port.
In case of phys switch id to find out if 2 netdevices share the same
switch parent.

^ permalink raw reply

* Re: [PATCH] net: tulip: Remove private "strncmp"
From: Grant Grundler @ 2014-12-04 19:35 UTC (permalink / raw)
  To: Rasmus Villemoes
  Cc: Grant Grundler, open list:TULIP NETWORK DRI..., open list
In-Reply-To: <1417689040-14958-1-git-send-email-linux@rasmusvillemoes.dk>

On Thu, Dec 4, 2014 at 2:30 AM, Rasmus Villemoes
<linux@rasmusvillemoes.dk> wrote:
> The comment says that the built-in strncmp didn't work. That is not
> surprising, as apparently "str" semantics are not really what is
> wanted (hint: de4x5_strncmp only stops when two different bytes are
> encountered or the end is reached; not if either byte happens to be
> 0). de4x5_strncmp is actually a memcmp (except for the signature and
> that bytes are not necessarily treated as unsigned char); since only
> the boolean value of the result is used we can just replace
> de4x5_strncmp with memcmp.
>
> Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
> ---
>
> Notes:
>     I don't know if the comment meant to say 3 bytes, or if the code
>     compares meaningful chunks of memory (the first three bytes of
>     &lp->srom span 1.5 fields, and the three bytes from (char*)&lp->srom +
>     0x10 are &lp->srom.{id_block_crc,reserved2,version} - it seems odd
>     that these chunks should ever be equal to each other and to the
>     enet_det[i]). Whether or not the current code works, this patch
>     shouldn't change the semantics, and I'd like to get rid of
>     de4x5_strncmp since it is not, in fact, a strncmp.

+1 I think your analysis is correct. The function appears to be
checking against a black list of MAC addresses that has two "broken"
devices MAC addresses.

Acked-by: Grant Grundler <grundler@parisc-linux.org>

thanks,
grant

ps. I don't like how de4x5_bad_srom() is structured but I can't test
these devices either.  Specifically, the offset of the MAC address
should be known and we should only be testing that offset to see if
it's "that vendor".

>  drivers/net/ethernet/dec/tulip/de4x5.c | 20 +++-----------------
>  1 file changed, 3 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/net/ethernet/dec/tulip/de4x5.c b/drivers/net/ethernet/dec/tulip/de4x5.c
> index cf8b6ff..badff18 100644
> --- a/drivers/net/ethernet/dec/tulip/de4x5.c
> +++ b/drivers/net/ethernet/dec/tulip/de4x5.c
> @@ -995,7 +995,6 @@ static void    de4x5_dbg_mii(struct net_device *dev, int k);
>  static void    de4x5_dbg_media(struct net_device *dev);
>  static void    de4x5_dbg_srom(struct de4x5_srom *p);
>  static void    de4x5_dbg_rx(struct sk_buff *skb, int len);
> -static int     de4x5_strncmp(char *a, char *b, int n);
>  static int     dc21041_infoleaf(struct net_device *dev);
>  static int     dc21140_infoleaf(struct net_device *dev);
>  static int     dc21142_infoleaf(struct net_device *dev);
> @@ -4102,8 +4101,7 @@ get_hw_addr(struct net_device *dev)
>  }
>
>  /*
> -** Test for enet addresses in the first 32 bytes. The built-in strncmp
> -** didn't seem to work here...?
> +** Test for enet addresses in the first 32 bytes.
>  */
>  static int
>  de4x5_bad_srom(struct de4x5_private *lp)
> @@ -4111,8 +4109,8 @@ de4x5_bad_srom(struct de4x5_private *lp)
>      int i, status = 0;
>
>      for (i = 0; i < ARRAY_SIZE(enet_det); i++) {
> -       if (!de4x5_strncmp((char *)&lp->srom, (char *)&enet_det[i], 3) &&
> -           !de4x5_strncmp((char *)&lp->srom+0x10, (char *)&enet_det[i], 3)) {
> +       if (!memcmp(&lp->srom, &enet_det[i], 3) &&
> +           !memcmp((char *)&lp->srom+0x10, &enet_det[i], 3)) {
>             if (i == 0) {
>                 status = SMC;
>             } else if (i == 1) {
> @@ -4125,18 +4123,6 @@ de4x5_bad_srom(struct de4x5_private *lp)
>      return status;
>  }
>
> -static int
> -de4x5_strncmp(char *a, char *b, int n)
> -{
> -    int ret=0;
> -
> -    for (;n && !ret; n--) {
> -       ret = *a++ - *b++;
> -    }
> -
> -    return ret;
> -}
> -
>  static void
>  srom_repair(struct net_device *dev, int card)
>  {
> --
> 2.0.4
>

^ permalink raw reply

* Re: [PATCH net-next] arch_fast_hash: avoid indirect function calls and implement hash in asm
From: Hannes Frederic Sowa @ 2014-12-04 19:32 UTC (permalink / raw)
  To: Jay Vosburgh
  Cc: netdev, Herbert Xu, Thomas Graf, Daniel Borkmann, Eric Dumazet
In-Reply-To: <15333.1417721231@famine>

Hi Jay,

On Do, 2014-12-04 at 11:27 -0800, Jay Vosburgh wrote:
> Hannes Frederic Sowa <hannes@stressinduktion.org> wrote:
> 
> >By default the arch_fast_hash hashing function pointers are initialized
> >to jhash(2). If during boot-up a CPU with SSE4.2 is detected they get
> >updated to the CRC32 ones. This dispatching scheme incurs a function
> >pointer lookup and indirect call for every hashing operation.
> >
> >To keep the number of clobbered registers short the hashing primitives
> >are implemented in assembler. This makes it easier to do the dispatch
> >by alternative_call.
> 
> 	I have tested this on the same system that panicked with the
> original (now reverted) implementation (commit e5a2c8999576 "fast_hash:
> avoid indirect function calls"), and it functions correctly and does not
> panic.
> 
> 	I looked at the disassembly, and, as a data point, on a
> non-SSE4.2 system, the code generated is not as efficient as Hannes'
> original test patch, found here:
> 
> http://comments.gmane.org/gmane.linux.network/338430
> 
> 	which produced code as follows:
> 
> 0xffffffffa00b6bb9 <ovs_flow_tbl_insert+0xb9>:  mov    %r15,0x348(%r14)
> 0xffffffffa00b6bc0 <ovs_flow_tbl_insert+0xc0>:  movzwl 0x28(%r15),%ecx
> 0xffffffffa00b6bc5 <ovs_flow_tbl_insert+0xc5>:  movzwl 0x2a(%r15),%esi
> 0xffffffffa00b6bca <ovs_flow_tbl_insert+0xca>:  movzwl %cx,%eax
> 0xffffffffa00b6bcd <ovs_flow_tbl_insert+0xcd>:  sub    %ecx,%esi
> 0xffffffffa00b6bcf <ovs_flow_tbl_insert+0xcf>:  lea    0x38(%r14,%rax,1),%rdi
> 0xffffffffa00b6bd4 <ovs_flow_tbl_insert+0xd4>:  sar    $0x2,%esi
> 0xffffffffa00b6bd7 <ovs_flow_tbl_insert+0xd7>:  callq  0xffffffff813a7810 <__jhash2>
> 0xffffffffa00b6bdc <ovs_flow_tbl_insert+0xdc>:  mov    %eax,0x30(%r14)
> 0xffffffffa00b6be0 <ovs_flow_tbl_insert+0xe0>:  mov    (%rbx),%r13
> 0xffffffffa00b6be3 <ovs_flow_tbl_insert+0xe3>:  mov    %r14,%rsi
> 0xffffffffa00b6be6 <ovs_flow_tbl_insert+0xe6>:  mov    %r13,%rdi
> 0xffffffffa00b6be9 <ovs_flow_tbl_insert+0xe9>:  callq  0xffffffffa00b61a0 <table_instance_insert>
> 
> 	This patch's code ends up as follows:
> 
> 0xffffffffa01b5a57 <ovs_flow_tbl_insert+0xb7>:	mov    %r15,0x348(%rcx)
> 0xffffffffa01b5a5e <ovs_flow_tbl_insert+0xbe>:	movzwl 0x28(%r15),%eax
> 0xffffffffa01b5a63 <ovs_flow_tbl_insert+0xc3>:	movzwl 0x2a(%r15),%esi
> 0xffffffffa01b5a68 <ovs_flow_tbl_insert+0xc8>:	movzwl %ax,%edx
> 0xffffffffa01b5a6b <ovs_flow_tbl_insert+0xcb>:	sub    %eax,%esi
> 0xffffffffa01b5a6d <ovs_flow_tbl_insert+0xcd>:	lea    0x38(%rcx,%rdx,1),%rdi
> 0xffffffffa01b5a72 <ovs_flow_tbl_insert+0xd2>:	xor    %edx,%edx
> 0xffffffffa01b5a74 <ovs_flow_tbl_insert+0xd4>:	sar    $0x2,%esi
> 0xffffffffa01b5a77 <ovs_flow_tbl_insert+0xd7>:	callq  0xffffffff813ae9f0 <__jhash_trampoline>
> 0xffffffffa01b5a7c <ovs_flow_tbl_insert+0xdc>:	mov    %eax,0x30(%rcx)
> 0xffffffffa01b5a7f <ovs_flow_tbl_insert+0xdf>:	mov    (%rbx),%r13
> 0xffffffffa01b5a82 <ovs_flow_tbl_insert+0xe2>:	mov    %rcx,%rsi
> 0xffffffffa01b5a85 <ovs_flow_tbl_insert+0xe5>:	mov    %r13,%rdi
> 0xffffffffa01b5a88 <ovs_flow_tbl_insert+0xe8>:	callq  0xffffffffa01b5030 <table_instance_insert>
> 
> 0xffffffff813ae9f0 <__jhash_trampoline>:	push   %rcx
> 0xffffffff813ae9f1 <__jhash_trampoline+0x1>:	push   %r8
> 0xffffffff813ae9f3 <__jhash_trampoline+0x3>:	push   %r9
> 0xffffffff813ae9f5 <__jhash_trampoline+0x5>:	push   %r10
> 0xffffffff813ae9f7 <__jhash_trampoline+0x7>:	push   %r11
> 0xffffffff813ae9f9 <__jhash_trampoline+0x9>:	callq  0xffffffff813ae8a0 <__jhash>
> 0xffffffff813ae9fe <__jhash_trampoline+0xe>:	pop    %r11
> 0xffffffff813aea00 <__jhash_trampoline+0x10>:	pop    %r10
> 0xffffffff813aea02 <__jhash_trampoline+0x12>:	pop    %r9
> 0xffffffff813aea04 <__jhash_trampoline+0x14>:	pop    %r8
> 0xffffffff813aea06 <__jhash_trampoline+0x16>:	pop    %rcx
> 0xffffffff813aea07 <__jhash_trampoline+0x17>:	retq   
> 
> 	In any event, this new patch does work correctly in my test that
> originally failed, and it's debatable how much optimizing for old
> systems is worthwhile.

Yes, that is expected. I also don't have a good idea on how to improve
the hashing on non-SSE4.2 systems in a reasonable amount of time.

> 	I only tested the non-SSE4.2 (i.e., old system) portion on
> x86_64.

I tried every possible setup this time, especially with openvswitch. I
covered ia32 with and without SSE4.2 as well as x86_64 and it always
behaved correctly. Last time the problem was that the static inline
didn't become a function in OVS, but during the testing with rhashtable
it got synthesized into a normal C call because of the indirect
reference.

Thanks a lot,
Hannes

^ permalink raw reply

* Re: [patch iproute2 1/6] iproute2: ipa: show switch id
From: Eric W. Biederman @ 2014-12-04 19:26 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: netdev, davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse,
	pshelar, azhou, ben, stephen, jeffrey.t.kirsher, vyasevic,
	xiyou.wangcong, john.r.fastabend, edumazet, jhs, sfeldma,
	f.fainelli, roopa, linville, jasowang, nicolas.dichtel,
	ryazanov.s.a, buytenh, aviadr, nbd, alexei.starovoitov,
	Neil.Jerram, ronye, simon.horman, alexander.h.duyck, john.ronciak,
	mleitner, shrijeet, gospo, bcrl, hemal
In-Reply-To: <20141204191926.GK1861@nanopsycho.orion>

Jiri Pirko <jiri@resnulli.us> writes:

>>So this id needs to be globally unique?
>
> No. It is enough to be unique within a single system. It serves for no
> more than to find out 2 ids are same or not, no other info value.
>
> So when the drivers uses sane ids (like mac for example, or in case of
> rocker an id which is passed by qemu command line), the chances of
> collision are very very close to none (never say never).

So the switch id isn't necessarily even as good as a manufacturers
serial number that changes between different models, and anyone who uses
this id must look at the driver to get uniqueness.

Yes what is needed in the comparison to get uniqueness in a single
system badly needs to be documented because that switch id is very much
not enough on it's own.

phys_port_id on the other hand is globally unique.  So please stop
saying that this is anything like phys_port_id.

Eric

^ permalink raw reply

* Re: [PATCH net-next] arch_fast_hash: avoid indirect function calls and implement hash in asm
From: Jay Vosburgh @ 2014-12-04 19:27 UTC (permalink / raw)
  To: Hannes Frederic Sowa
  Cc: netdev, Herbert Xu, Thomas Graf, Daniel Borkmann, Eric Dumazet
In-Reply-To: <e77237174e1b8d743ef5171e05abde82bc54af37.1417696901.git.hannes@stressinduktion.org>

Hannes Frederic Sowa <hannes@stressinduktion.org> wrote:

>By default the arch_fast_hash hashing function pointers are initialized
>to jhash(2). If during boot-up a CPU with SSE4.2 is detected they get
>updated to the CRC32 ones. This dispatching scheme incurs a function
>pointer lookup and indirect call for every hashing operation.
>
>To keep the number of clobbered registers short the hashing primitives
>are implemented in assembler. This makes it easier to do the dispatch
>by alternative_call.

	I have tested this on the same system that panicked with the
original (now reverted) implementation (commit e5a2c8999576 "fast_hash:
avoid indirect function calls"), and it functions correctly and does not
panic.

	I looked at the disassembly, and, as a data point, on a
non-SSE4.2 system, the code generated is not as efficient as Hannes'
original test patch, found here:

http://comments.gmane.org/gmane.linux.network/338430

	which produced code as follows:

0xffffffffa00b6bb9 <ovs_flow_tbl_insert+0xb9>:  mov    %r15,0x348(%r14)
0xffffffffa00b6bc0 <ovs_flow_tbl_insert+0xc0>:  movzwl 0x28(%r15),%ecx
0xffffffffa00b6bc5 <ovs_flow_tbl_insert+0xc5>:  movzwl 0x2a(%r15),%esi
0xffffffffa00b6bca <ovs_flow_tbl_insert+0xca>:  movzwl %cx,%eax
0xffffffffa00b6bcd <ovs_flow_tbl_insert+0xcd>:  sub    %ecx,%esi
0xffffffffa00b6bcf <ovs_flow_tbl_insert+0xcf>:  lea    0x38(%r14,%rax,1),%rdi
0xffffffffa00b6bd4 <ovs_flow_tbl_insert+0xd4>:  sar    $0x2,%esi
0xffffffffa00b6bd7 <ovs_flow_tbl_insert+0xd7>:  callq  0xffffffff813a7810 <__jhash2>
0xffffffffa00b6bdc <ovs_flow_tbl_insert+0xdc>:  mov    %eax,0x30(%r14)
0xffffffffa00b6be0 <ovs_flow_tbl_insert+0xe0>:  mov    (%rbx),%r13
0xffffffffa00b6be3 <ovs_flow_tbl_insert+0xe3>:  mov    %r14,%rsi
0xffffffffa00b6be6 <ovs_flow_tbl_insert+0xe6>:  mov    %r13,%rdi
0xffffffffa00b6be9 <ovs_flow_tbl_insert+0xe9>:  callq  0xffffffffa00b61a0 <table_instance_insert>

	This patch's code ends up as follows:

0xffffffffa01b5a57 <ovs_flow_tbl_insert+0xb7>:	mov    %r15,0x348(%rcx)
0xffffffffa01b5a5e <ovs_flow_tbl_insert+0xbe>:	movzwl 0x28(%r15),%eax
0xffffffffa01b5a63 <ovs_flow_tbl_insert+0xc3>:	movzwl 0x2a(%r15),%esi
0xffffffffa01b5a68 <ovs_flow_tbl_insert+0xc8>:	movzwl %ax,%edx
0xffffffffa01b5a6b <ovs_flow_tbl_insert+0xcb>:	sub    %eax,%esi
0xffffffffa01b5a6d <ovs_flow_tbl_insert+0xcd>:	lea    0x38(%rcx,%rdx,1),%rdi
0xffffffffa01b5a72 <ovs_flow_tbl_insert+0xd2>:	xor    %edx,%edx
0xffffffffa01b5a74 <ovs_flow_tbl_insert+0xd4>:	sar    $0x2,%esi
0xffffffffa01b5a77 <ovs_flow_tbl_insert+0xd7>:	callq  0xffffffff813ae9f0 <__jhash_trampoline>
0xffffffffa01b5a7c <ovs_flow_tbl_insert+0xdc>:	mov    %eax,0x30(%rcx)
0xffffffffa01b5a7f <ovs_flow_tbl_insert+0xdf>:	mov    (%rbx),%r13
0xffffffffa01b5a82 <ovs_flow_tbl_insert+0xe2>:	mov    %rcx,%rsi
0xffffffffa01b5a85 <ovs_flow_tbl_insert+0xe5>:	mov    %r13,%rdi
0xffffffffa01b5a88 <ovs_flow_tbl_insert+0xe8>:	callq  0xffffffffa01b5030 <table_instance_insert>

0xffffffff813ae9f0 <__jhash_trampoline>:	push   %rcx
0xffffffff813ae9f1 <__jhash_trampoline+0x1>:	push   %r8
0xffffffff813ae9f3 <__jhash_trampoline+0x3>:	push   %r9
0xffffffff813ae9f5 <__jhash_trampoline+0x5>:	push   %r10
0xffffffff813ae9f7 <__jhash_trampoline+0x7>:	push   %r11
0xffffffff813ae9f9 <__jhash_trampoline+0x9>:	callq  0xffffffff813ae8a0 <__jhash>
0xffffffff813ae9fe <__jhash_trampoline+0xe>:	pop    %r11
0xffffffff813aea00 <__jhash_trampoline+0x10>:	pop    %r10
0xffffffff813aea02 <__jhash_trampoline+0x12>:	pop    %r9
0xffffffff813aea04 <__jhash_trampoline+0x14>:	pop    %r8
0xffffffff813aea06 <__jhash_trampoline+0x16>:	pop    %rcx
0xffffffff813aea07 <__jhash_trampoline+0x17>:	retq   

	In any event, this new patch does work correctly in my test that
originally failed, and it's debatable how much optimizing for old
systems is worthwhile.

	I only tested the non-SSE4.2 (i.e., old system) portion on
x86_64.

Tested-by: Jay Vosburgh <jay.vosburgh@canonical.com>

	-J

>Cc: Herbert Xu <herbert@gondor.apana.org.au>
>Cc: Jay Vosburgh <jay.vosburgh@canonical.com>
>Cc: Thomas Graf <tgraf@suug.ch>
>Cc: Daniel Borkmann <dborkman@redhat.com>
>Cc: Eric Dumazet <eric.dumazet@gmail.com>
>Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
>---
> arch/x86/include/asm/hash.h      |  53 ++++++++++-
> arch/x86/kernel/i386_ksyms_32.c  |   6 ++
> arch/x86/kernel/x8664_ksyms_64.c |   6 ++
> arch/x86/lib/Makefile            |   2 +-
> arch/x86/lib/arch_hash.S         | 192 +++++++++++++++++++++++++++++++++++++++
> arch/x86/lib/hash.c              |  92 -------------------
> arch/x86/lib/jhash.c             |   6 ++
> include/asm-generic/hash.h       |  18 +++-
> include/linux/hash.h             |  34 -------
> lib/Makefile                     |   2 +-
> lib/hash.c                       |  39 --------
> net/openvswitch/flow_table.c     |   2 +-
> 12 files changed, 280 insertions(+), 172 deletions(-)
> create mode 100644 arch/x86/lib/arch_hash.S
> delete mode 100644 arch/x86/lib/hash.c
> create mode 100644 arch/x86/lib/jhash.c
> delete mode 100644 lib/hash.c
>
>diff --git a/arch/x86/include/asm/hash.h b/arch/x86/include/asm/hash.h
>index e8c58f8..620081b 100644
>--- a/arch/x86/include/asm/hash.h
>+++ b/arch/x86/include/asm/hash.h
>@@ -1,7 +1,56 @@
> #ifndef _ASM_X86_HASH_H
> #define _ASM_X86_HASH_H
> 
>-struct fast_hash_ops;
>-extern void setup_arch_fast_hash(struct fast_hash_ops *ops);
>+#include <linux/cpufeature.h>
>+#include <asm/alternative.h>
>+
>+#include <linux/jhash.h>
>+
>+#ifdef CONFIG_AS_CRC32
>+
>+u32 __jhash_trampoline(const void *data, u32 len, u32 seed);
>+u32 __sse42_crc32(const void *data, u32 len, u32 seed);
>+
>+#ifdef CONFIG_X86_64
>+
>+static inline u32 arch_fast_hash(const void *data, u32 len, u32 seed)
>+{
>+	u32 hash;
>+
>+	alternative_call(__jhash_trampoline, __sse42_crc32, X86_FEATURE_XMM4_2,
>+			 ASM_OUTPUT2("=a" (hash), "=D" (data), "=S" (len),
>+				     "=d" (seed)),
>+			 "1" (data), "2" (len), "3" (seed)
>+			 : "memory", "cc");
>+
>+	return hash;
>+}
>+
>+#else /* CONFIG_X86_64 */
>+
>+static inline u32 arch_fast_hash(const void *data, u32 len, u32 seed)
>+{
>+	u32 hash;
>+
>+	alternative_call(__jhash_trampoline, __sse42_crc32, X86_FEATURE_XMM4_2,
>+			 ASM_OUTPUT2("=a" (hash), "=d" (len), "=c" (seed)),
>+			 "0" (data), "1" (len), "2" (seed)
>+			 : "memory", "cc");
>+
>+	return hash;
>+}
>+
>+#endif /* CONFIG_x86_64 */
>+
>+#else /* CONFIG_AS_CRC32 */
>+
>+u32 __jhash(const void *data, u32 len, u32 seed);
>+
>+static inline u32 arch_fast_hash(const void *data, u32 len, u32 seed)
>+{
>+	return __jhash(data, len, seed);
>+}
>+
>+#endif
> 
> #endif /* _ASM_X86_HASH_H */
>diff --git a/arch/x86/kernel/i386_ksyms_32.c b/arch/x86/kernel/i386_ksyms_32.c
>index 05fd74f..afb98da 100644
>--- a/arch/x86/kernel/i386_ksyms_32.c
>+++ b/arch/x86/kernel/i386_ksyms_32.c
>@@ -1,4 +1,5 @@
> #include <linux/module.h>
>+#include <linux/hash.h>
> 
> #include <asm/checksum.h>
> #include <asm/pgtable.h>
>@@ -38,6 +39,11 @@ EXPORT_SYMBOL(strstr);
> EXPORT_SYMBOL(csum_partial);
> EXPORT_SYMBOL(empty_zero_page);
> 
>+#ifdef CONFIG_AS_CRC32
>+EXPORT_SYMBOL(__sse42_crc32);
>+EXPORT_SYMBOL(__jhash_trampoline);
>+#endif
>+
> #ifdef CONFIG_PREEMPT
> EXPORT_SYMBOL(___preempt_schedule);
> #ifdef CONFIG_CONTEXT_TRACKING
>diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c
>index 0406819..1094c13 100644
>--- a/arch/x86/kernel/x8664_ksyms_64.c
>+++ b/arch/x86/kernel/x8664_ksyms_64.c
>@@ -3,6 +3,7 @@
> 
> #include <linux/module.h>
> #include <linux/smp.h>
>+#include <linux/hash.h>
> 
> #include <net/checksum.h>
> 
>@@ -42,6 +43,11 @@ EXPORT_SYMBOL(clear_page);
> 
> EXPORT_SYMBOL(csum_partial);
> 
>+#ifdef CONFIG_AS_CRC32
>+EXPORT_SYMBOL(__sse42_crc32);
>+EXPORT_SYMBOL(__jhash_trampoline);
>+#endif
>+
> /*
>  * Export string functions. We normally rely on gcc builtin for most of these,
>  * but gcc sometimes decides not to inline them.
>diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
>index db92793..168bbef 100644
>--- a/arch/x86/lib/Makefile
>+++ b/arch/x86/lib/Makefile
>@@ -23,7 +23,7 @@ lib-y += memcpy_$(BITS).o
> lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
> lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o
> 
>-obj-y += msr.o msr-reg.o msr-reg-export.o hash.o
>+obj-y += msr.o msr-reg.o msr-reg-export.o jhash.o arch_hash.o
> 
> ifeq ($(CONFIG_X86_32),y)
>         obj-y += atomic64_32.o
>diff --git a/arch/x86/lib/arch_hash.S b/arch/x86/lib/arch_hash.S
>new file mode 100644
>index 0000000..ff526a4
>--- /dev/null
>+++ b/arch/x86/lib/arch_hash.S
>@@ -0,0 +1,192 @@
>+#include <linux/linkage.h>
>+#include <asm/dwarf2.h>
>+#include <asm/calling.h>
>+
>+#ifdef CONFIG_AS_CRC32
>+
>+#ifdef CONFIG_X86_64
>+
>+ENTRY(__jhash_trampoline)
>+	CFI_STARTPROC
>+
>+	pushq_cfi %rcx
>+	pushq_cfi %r8
>+	pushq_cfi %r9
>+	pushq_cfi %r10
>+	pushq_cfi %r11
>+
>+	call __jhash
>+
>+	popq_cfi %r11
>+	popq_cfi %r10
>+	popq_cfi %r9
>+	popq_cfi %r8
>+	popq_cfi %rcx
>+
>+	retq
>+
>+	CFI_ENDPROC
>+ENDPROC(__jhash_trampoline)
>+
>+ENTRY(__sse42_crc32)
>+	CFI_STARTPROC
>+
>+	movq %rdx, %rax
>+	cmpq $0x40, %rsi
>+	jb .Lcrc_32bytes
>+	subq $0x40, %rsi
>+
>+.Lcrc_64bytes:
>+	subq $0x40, %rsi
>+	crc32q 0*8(%rdi), %rax
>+	crc32q 1*8(%rdi), %rax
>+	crc32q 2*8(%rdi), %rax
>+	crc32q 3*8(%rdi), %rax
>+	crc32q 4*8(%rdi), %rax
>+	crc32q 5*8(%rdi), %rax
>+	crc32q 6*8(%rdi), %rax
>+	crc32q 7*8(%rdi), %rax
>+	leaq   8*8(%rdi), %rdi
>+	jae .Lcrc_64bytes
>+	addq $0x40, %rsi
>+
>+.Lcrc_32bytes:
>+	cmpq $0x20, %rsi
>+	jb .Lcrc_16bytes
>+
>+	subq $0x20, %rsi
>+	crc32q 0*8(%rdi), %rax
>+	crc32q 1*8(%rdi), %rax
>+	crc32q 2*8(%rdi), %rax
>+	crc32q 3*8(%rdi), %rax
>+	leaq   4*8(%rdi), %rdi
>+
>+.Lcrc_16bytes:
>+	cmpq $0x10, %rsi
>+	jb .Lcrc_8bytes
>+
>+	subq $0x10, %rsi
>+	crc32q 0*8(%rdi), %rax
>+	crc32q 1*8(%rdi), %rax
>+	leaq   2*8(%rdi), %rdi
>+
>+.Lcrc_8bytes:
>+	cmpq $0x8, %rsi
>+	jb .Lcrc_4bytes
>+
>+	subq $0x8, %rsi
>+	crc32q (%rdi), %rax
>+	leaq 1*8(%rdi), %rdi
>+
>+.Lcrc_4bytes:
>+	cmpq $0x4, %rsi
>+	jb .Lcrc_2bytes
>+
>+	subq $0x4, %rsi
>+	crc32l (%rdi), %eax
>+	leaq   1*4(%rdi), %rdi
>+
>+.Lcrc_2bytes:
>+	cmpq $0x2, %rsi
>+	jb .Lcrc_1bytes
>+
>+	subq $0x2, %rsi
>+	crc32w (%rdi), %eax
>+	leaq 1*2(%rdi), %rdi
>+
>+.Lcrc_1bytes:
>+	cmpq $0x1, %rsi
>+	jb .Lend
>+
>+	crc32b (%rdi), %eax
>+.Lend:
>+	retq
>+	CFI_ENDPROC
>+ENDPROC(__sse42_crc32)
>+
>+#else /* CONFIG_X86_32 */
>+
>+ENTRY(__jhash_trampoline)
>+	CFI_STARTPROC
>+
>+	call __jhash
>+
>+	retl
>+	CFI_ENDPROC
>+ENDPROC(__jhash_trampoline)
>+
>+ENTRY(__sse42_crc32)
>+	CFI_STARTPROC
>+
>+	xchgl %eax,%ecx
>+	xchgl %edx,%ecx
>+
>+	cmpl $0x20, %ecx
>+	jb .Lcrc_16bytes
>+	subl $0x20, %ecx
>+
>+.Lcrc_32bytes:
>+	subl $0x20, %ecx
>+	crc32l 0*4(%edx), %eax
>+	crc32l 1*4(%edx), %eax
>+	crc32l 2*4(%edx), %eax
>+	crc32l 3*4(%edx), %eax
>+	crc32l 4*4(%edx), %eax
>+	crc32l 5*4(%edx), %eax
>+	crc32l 6*4(%edx), %eax
>+	crc32l 7*4(%edx), %eax
>+	leal   8*4(%edx), %edx
>+	jae .Lcrc_32bytes
>+	addl $0x20, %ecx
>+
>+.Lcrc_16bytes:
>+	cmpl $0x10, %ecx
>+	jb .Lcrc_8bytes
>+
>+	subl $0x10, %ecx
>+	crc32l 0*4(%edx), %eax
>+	crc32l 1*4(%edx), %eax
>+	crc32l 2*4(%edx), %eax
>+	crc32l 3*4(%edx), %eax
>+	leal   4*4(%edx), %edx
>+
>+.Lcrc_8bytes:
>+	cmpl $0x8, %ecx
>+	jb .Lcrc_4bytes
>+
>+	subl $0x8, %ecx
>+	crc32l 0*4(%edx), %eax
>+	crc32l 1*4(%edx), %eax
>+	leal   2*4(%edx), %edx
>+
>+.Lcrc_4bytes:
>+	cmpl $0x4, %ecx
>+	jb .Lcrc_2bytes
>+
>+	subl $0x4, %ecx
>+	crc32l 0*4(%edx), %eax
>+	leal   1*4(%edx), %edx
>+
>+.Lcrc_2bytes:
>+	cmpl $0x2, %ecx
>+	jb .Lcrc_1bytes
>+
>+	subl $0x2, %ecx
>+	crc32w (%edx), %eax
>+	leal   1*2(%edx), %edx
>+
>+.Lcrc_1bytes:
>+	cmpl $0x1, %ecx
>+	jb .Lend
>+
>+	crc32b (%edx), %eax
>+
>+.Lend:
>+	retl
>+
>+	CFI_ENDPROC
>+ENDPROC(__sse42_crc32)
>+
>+#endif
>+
>+#endif /* CONFIG_AS_CRC32 */
>diff --git a/arch/x86/lib/hash.c b/arch/x86/lib/hash.c
>deleted file mode 100644
>index ff4fa51..0000000
>--- a/arch/x86/lib/hash.c
>+++ /dev/null
>@@ -1,92 +0,0 @@
>-/*
>- * Some portions derived from code covered by the following notice:
>- *
>- * Copyright (c) 2010-2013 Intel Corporation. All rights reserved.
>- * All rights reserved.
>- *
>- * Redistribution and use in source and binary forms, with or without
>- * modification, are permitted provided that the following conditions
>- * are met:
>- *
>- *   * Redistributions of source code must retain the above copyright
>- *     notice, this list of conditions and the following disclaimer.
>- *   * Redistributions in binary form must reproduce the above copyright
>- *     notice, this list of conditions and the following disclaimer in
>- *     the documentation and/or other materials provided with the
>- *     distribution.
>- *   * Neither the name of Intel Corporation nor the names of its
>- *     contributors may be used to endorse or promote products derived
>- *     from this software without specific prior written permission.
>- *
>- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
>- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
>- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
>- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
>- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
>- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
>- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
>- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
>- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>- */
>-
>-#include <linux/hash.h>
>-#include <linux/init.h>
>-
>-#include <asm/processor.h>
>-#include <asm/cpufeature.h>
>-#include <asm/hash.h>
>-
>-static inline u32 crc32_u32(u32 crc, u32 val)
>-{
>-#ifdef CONFIG_AS_CRC32
>-	asm ("crc32l %1,%0\n" : "+r" (crc) : "rm" (val));
>-#else
>-	asm (".byte 0xf2, 0x0f, 0x38, 0xf1, 0xc1" : "+a" (crc) : "c" (val));
>-#endif
>-	return crc;
>-}
>-
>-static u32 intel_crc4_2_hash(const void *data, u32 len, u32 seed)
>-{
>-	const u32 *p32 = (const u32 *) data;
>-	u32 i, tmp = 0;
>-
>-	for (i = 0; i < len / 4; i++)
>-		seed = crc32_u32(seed, *p32++);
>-
>-	switch (len & 3) {
>-	case 3:
>-		tmp |= *((const u8 *) p32 + 2) << 16;
>-		/* fallthrough */
>-	case 2:
>-		tmp |= *((const u8 *) p32 + 1) << 8;
>-		/* fallthrough */
>-	case 1:
>-		tmp |= *((const u8 *) p32);
>-		seed = crc32_u32(seed, tmp);
>-		break;
>-	}
>-
>-	return seed;
>-}
>-
>-static u32 intel_crc4_2_hash2(const u32 *data, u32 len, u32 seed)
>-{
>-	const u32 *p32 = (const u32 *) data;
>-	u32 i;
>-
>-	for (i = 0; i < len; i++)
>-		seed = crc32_u32(seed, *p32++);
>-
>-	return seed;
>-}
>-
>-void __init setup_arch_fast_hash(struct fast_hash_ops *ops)
>-{
>-	if (cpu_has_xmm4_2) {
>-		ops->hash  = intel_crc4_2_hash;
>-		ops->hash2 = intel_crc4_2_hash2;
>-	}
>-}
>diff --git a/arch/x86/lib/jhash.c b/arch/x86/lib/jhash.c
>new file mode 100644
>index 0000000..ab4b408
>--- /dev/null
>+++ b/arch/x86/lib/jhash.c
>@@ -0,0 +1,6 @@
>+#include <linux/jhash.h>
>+
>+u32 __jhash(const void *data, u32 len, u32 seed)
>+{
>+	return jhash(data, len, seed);
>+}
>diff --git a/include/asm-generic/hash.h b/include/asm-generic/hash.h
>index b631284..07b8892 100644
>--- a/include/asm-generic/hash.h
>+++ b/include/asm-generic/hash.h
>@@ -1,9 +1,23 @@
> #ifndef __ASM_GENERIC_HASH_H
> #define __ASM_GENERIC_HASH_H
> 
>-struct fast_hash_ops;
>-static inline void setup_arch_fast_hash(struct fast_hash_ops *ops)
>+#include <linux/jhash.h>
>+
>+/**
>+ *	arch_fast_hash - Caclulates a hash over a given buffer that can have
>+ *			 arbitrary size. This function will eventually use an
>+ *			 architecture-optimized hashing implementation if
>+ *			 available, and trades off distribution for speed.
>+ *
>+ *	@data: buffer to hash
>+ *	@len: length of buffer in bytes
>+ *	@seed: start seed
>+ *
>+ *	Returns 32bit hash.
>+ */
>+u32 arch_fast_hash(const void *data, u32 len, u32 seed)
> {
>+	return jhash(data, len, seed);
> }
> 
> #endif /* __ASM_GENERIC_HASH_H */
>diff --git a/include/linux/hash.h b/include/linux/hash.h
>index d0494c3..6e8fb02 100644
>--- a/include/linux/hash.h
>+++ b/include/linux/hash.h
>@@ -84,38 +84,4 @@ static inline u32 hash32_ptr(const void *ptr)
> 	return (u32)val;
> }
> 
>-struct fast_hash_ops {
>-	u32 (*hash)(const void *data, u32 len, u32 seed);
>-	u32 (*hash2)(const u32 *data, u32 len, u32 seed);
>-};
>-
>-/**
>- *	arch_fast_hash - Caclulates a hash over a given buffer that can have
>- *			 arbitrary size. This function will eventually use an
>- *			 architecture-optimized hashing implementation if
>- *			 available, and trades off distribution for speed.
>- *
>- *	@data: buffer to hash
>- *	@len: length of buffer in bytes
>- *	@seed: start seed
>- *
>- *	Returns 32bit hash.
>- */
>-extern u32 arch_fast_hash(const void *data, u32 len, u32 seed);
>-
>-/**
>- *	arch_fast_hash2 - Caclulates a hash over a given buffer that has a
>- *			  size that is of a multiple of 32bit words. This
>- *			  function will eventually use an architecture-
>- *			  optimized hashing implementation if available,
>- *			  and trades off distribution for speed.
>- *
>- *	@data: buffer to hash (must be 32bit padded)
>- *	@len: number of 32bit words
>- *	@seed: start seed
>- *
>- *	Returns 32bit hash.
>- */
>-extern u32 arch_fast_hash2(const u32 *data, u32 len, u32 seed);
>-
> #endif /* _LINUX_HASH_H */
>diff --git a/lib/Makefile b/lib/Makefile
>index 0211d2b..4b9baa4 100644
>--- a/lib/Makefile
>+++ b/lib/Makefile
>@@ -26,7 +26,7 @@ obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
> 	 bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \
> 	 gcd.o lcm.o list_sort.o uuid.o flex_array.o iovec.o clz_ctz.o \
> 	 bsearch.o find_last_bit.o find_next_bit.o llist.o memweight.o kfifo.o \
>-	 percpu-refcount.o percpu_ida.o hash.o rhashtable.o reciprocal_div.o
>+	 percpu-refcount.o percpu_ida.o rhashtable.o reciprocal_div.o
> obj-y += string_helpers.o
> obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o
> obj-y += kstrtox.o
>diff --git a/lib/hash.c b/lib/hash.c
>deleted file mode 100644
>index fea973f..0000000
>--- a/lib/hash.c
>+++ /dev/null
>@@ -1,39 +0,0 @@
>-/* General purpose hashing library
>- *
>- * That's a start of a kernel hashing library, which can be extended
>- * with further algorithms in future. arch_fast_hash{2,}() will
>- * eventually resolve to an architecture optimized implementation.
>- *
>- * Copyright 2013 Francesco Fusco <ffusco@redhat.com>
>- * Copyright 2013 Daniel Borkmann <dborkman@redhat.com>
>- * Copyright 2013 Thomas Graf <tgraf@redhat.com>
>- * Licensed under the GNU General Public License, version 2.0 (GPLv2)
>- */
>-
>-#include <linux/jhash.h>
>-#include <linux/hash.h>
>-#include <linux/cache.h>
>-
>-static struct fast_hash_ops arch_hash_ops __read_mostly = {
>-	.hash  = jhash,
>-	.hash2 = jhash2,
>-};
>-
>-u32 arch_fast_hash(const void *data, u32 len, u32 seed)
>-{
>-	return arch_hash_ops.hash(data, len, seed);
>-}
>-EXPORT_SYMBOL_GPL(arch_fast_hash);
>-
>-u32 arch_fast_hash2(const u32 *data, u32 len, u32 seed)
>-{
>-	return arch_hash_ops.hash2(data, len, seed);
>-}
>-EXPORT_SYMBOL_GPL(arch_fast_hash2);
>-
>-static int __init hashlib_init(void)
>-{
>-	setup_arch_fast_hash(&arch_hash_ops);
>-	return 0;
>-}
>-early_initcall(hashlib_init);
>diff --git a/net/openvswitch/flow_table.c b/net/openvswitch/flow_table.c
>index e0a7fef..79bc65d 100644
>--- a/net/openvswitch/flow_table.c
>+++ b/net/openvswitch/flow_table.c
>@@ -366,7 +366,7 @@ static u32 flow_hash(const struct sw_flow_key *key, int key_start,
> 	/* Make sure number of hash bytes are multiple of u32. */
> 	BUILD_BUG_ON(sizeof(long) % sizeof(u32));
> 
>-	return arch_fast_hash2(hash_key, hash_u32s, 0);
>+	return arch_fast_hash(hash_key, hash_u32s, 0);
> }
> 
> static int flow_key_start(const struct sw_flow_key *key)
>-- 
>1.9.3

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

^ permalink raw reply

* Re: [linux-nics] [PATCHv3 net] i40e: Implement ndo_gso_check()
From: Jeff Kirsher @ 2014-12-04 19:20 UTC (permalink / raw)
  To: Sergei Shtylyov
  Cc: Joe Stringer, netdev, linux.nics, jesse, linux-kernel, therbert
In-Reply-To: <5480B1F0.9090407@cogentembedded.com>

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

On Thu, 2014-12-04 at 22:11 +0300, Sergei Shtylyov wrote:
> Hello.
> 
> On 12/04/2014 09:39 PM, Joe Stringer wrote:
> 
> > ndo_gso_check() was recently introduced to allow NICs to report the
> > offloading support that they have on a per-skb basis. Add an
> > implementation for this driver which checks for IPIP, GRE, UDP tunnels.
> 
> > Signed-off-by: Joe Stringer <joestringer@nicira.com>
> > ---
> > v3: Drop IPIP and GRE (no driver support even though hw supports it).
> >      Check for UDP outer protocol for UDP tunnels.
> > v2: Expand to include IP in IP and IPv4/IPv6 inside GRE/UDP tunnels.
> >      Add MAX_INNER_LENGTH (as 80).
> > ---
> >   drivers/net/ethernet/intel/i40e/i40e_main.c |   26 ++++++++++++++++++++++++++
> >   1 file changed, 26 insertions(+)
> 
> > diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
> > index c3a7f4a..0d6493a 100644
> > --- a/drivers/net/ethernet/intel/i40e/i40e_main.c
> > +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
> > @@ -7447,6 +7447,31 @@ static int i40e_ndo_fdb_dump(struct sk_buff *skb,
> >
> >   #endif /* USE_DEFAULT_FDB_DEL_DUMP */
> >   #endif /* HAVE_FDB_OPS */
> 
>     Need empty line here, I think.

Nope, look above the #endif's, that is the blank line that you are
wanting if the above #ifdefs are defined and if not, the blank line is
before the #ifdef's.  So if you were to add a blank line as you
requested, there is a possibility of 2 blank lines in a row.  So it is
not needed.

> 
> > +static bool i40e_gso_check(struct sk_buff *skb, struct net_device *dev)
> > +{
> > +	if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL) {
> > +		unsigned char *ihdr;
> > +
> > +		if (skb->protocol != IPPROTO_UDP ||
> > +		    skb->inner_protocol_type != ENCAP_TYPE_ETHER)
> > +			return false;
> > +
> > +		if (skb->inner_protocol == htons(ETH_P_TEB))
> > +			ihdr = skb_inner_mac_header(skb);
> > +		else if (skb->inner_protocol == htons(ETH_P_IP) ||
> > +			 skb->inner_protocol == htons(ETH_P_IPV6))
> > +			ihdr = skb_inner_network_header(skb);
> > +		else
> > +			return false;
> 
>     The above is asking to be a *switch* instead, no?
> 
> > +
> > +#define MAX_TUNNEL_HDR_LEN	80
> 
>     I'd #define this just above the function, if not at the start of the file...
> 
> [...]
> 
> WBR, Sergei
> 
> _______________________________________________
> Linux-nics mailing list
> Linux-nics@intel.com



[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply

* Re: [patch iproute2 1/6] iproute2: ipa: show switch id
From: Jiri Pirko @ 2014-12-04 19:19 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: netdev, davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse,
	pshelar, azhou, ben, stephen, jeffrey.t.kirsher, vyasevic,
	xiyou.wangcong, john.r.fastabend, edumazet, jhs, sfeldma,
	f.fainelli, roopa, linville, jasowang, nicolas.dichtel,
	ryazanov.s.a, buytenh, aviadr, nbd, alexei.starovoitov,
	Neil.Jerram, ronye, simon.horman, alexander.h.duyck, john.ronciak,
	mleitner, shrijeet, gospo, bcrl, hemal
In-Reply-To: <87k327450a.fsf@x220.int.ebiederm.org>

Thu, Dec 04, 2014 at 07:57:41PM CET, ebiederm@xmission.com wrote:
>Jiri Pirko <jiri@resnulli.us> writes:
>
>> Thu, Dec 04, 2014 at 06:52:49PM CET, ebiederm@xmission.com wrote:
>>>Jiri Pirko <jiri@resnulli.us> writes:
>>>
>>>> Thu, Dec 04, 2014 at 05:15:04PM CET, ebiederm@xmission.com wrote:
>>>>>Jiri Pirko <jiri@resnulli.us> writes:
>>>>>
>>>>>Would someone please explain to me what a switch id is?
>>>>>
>>>>>I looked in the kernel source, and I looked here and while I know
>>>>>switches I don't have a clue what a switch id is.
>>>>>
>>>>>My primary concern at this point is that you have introduced a global
>>>>>identifier that is isn't a hardware property (it certainly does not look
>>>>>like a mac address) and that is unique across network namespaces and
>>>>>thus breaks checkpoint/restart (aka CRIU).
>>>>
>>>> IFLA_PHYS_SWITCH_ID is very similar to IFLA_PHYS_PORT_ID. It is
>>>> generated by the driver and ensures that there is the same switch id for
>>>> all ports belonging to the same switch chip/asic. It is up to the driver
>>>> how to implement the id. I would like to point you to driver
>>>> implementing ndo_get_phys_port_id
>>>
>>>Looking at ndo_get_phys_port_id it is just the per port mac address.  Or
>>>guid in the case of infiniband.  Which really makes me wonder why we
>>>didn't use the same abstractions in the code for address types that we
>>>do for hardware addresses.
>>>
>>>Using mac address or other hardware addresses that are used for layer 2
>>>addressing makes sense to me.  There is a long tradition of that and as
>>>I recall protocols like STP actually requiring having a different mac
>>>address per port.
>>>
>>>When I asked the question I thought the switch id was going to be
>>>something like the ifindex, the software index of a network device.
>>>
>>>
>>>Finally having tracked down the rocker implementation of 
>>>rocker_port_switch_parent_id_get I see it you are reading some 64bit
>>>hardware register.
>>>
>>>Which leads me to ask what are the semantics of switch_id?
>>>
>>>Is the switch id an identifier with a prefix from IEEE and assigned by
>>>the manufacture so that it is guaranteed to the tolerances of the
>>>manufacturing process to be globally unique?
>>
>> It is up to the driver what to use. It can use mac addr. This is same as
>> for phys port id.
>
>My reading of the code says the phys port id is the layer 2 hardware
>address of the port.  Certainly that is the case for all of the
>implementations now and it would be insane for it to be anything else.
>
>>>Is the switch id a random number that is statistically likely to be
>>>globally unique because you have enough bits?   As I recall you need
>>>at least 128 bits to have a reasonable chance of a random number
>>>avoiding the birthday paradox.
>>>
>>>Do we need some kind of manufacturer id to tell one switch id from
>>>another?
>>>
>>>Is the switch id persistent across reboots?
>>
>> Yes it is (as for phys port id).
>
>>>>>Also what in the world does PHYS mean in IFLA_PHYS_SWITCH_ID?  Does that
>>>>>mean we can't have a purely software implementation of this interface?
>>>>>Given that we will want a software implementation at some point
>>>>>including PHYS in the name seems completely wrong.
>>>>
>>>> We can remove the "PHYS", no problem. I do not understand what you say
>>>> about "software implementation". The point is to allow hw switch/ish
>>>> chips to be supported.
>>>
>>>If we are talking about something typically stored in a eeprom like a
>>>mac address phys seems appropriate.
>>
>> Yes, we are.
>>
>>>
>>>Still having a definition of this switch id clean clear enough that
>>>net/bridge and drivers/net/macvlan can implement it seems important.
>>
>> I don't understand why would net/bridge or driver/net/macvlan want to
>> implement this. The purpose is to group ports/netdevs which are part of
>> the same hw switch.
>
>Certainly all of the macvlan devices are part of the same logical
>switch, and are all the same hardware.
>
>>>Even more important is having a definition of switch id clear enough
>>>that userspace can use the switch id to do something useful.
>>
>> Userspace threats this the same it treats phys port id.
>>
>> if two ports/netdevs has same switch id, they belong under same hw
>> switch. That's all.
>
>So this id needs to be globally unique?

No. It is enough to be unique within a single system. It serves for no
more than to find out 2 ids are same or not, no other info value.

So when the drivers uses sane ids (like mac for example, or in case of
rocker an id which is passed by qemu command line), the chances of
collision are very very close to none (never say never).

>
>How does the rocket driver achieve global uniquness?  Is the rocket
>driver using an IEEE assigned prefix based id like the ethernet mac
>address?
>
>This is an important detail as ensuring global uniqueness can take a lot
>of work so there needs to be a general agreement on how global
>uniqueness is achieved.
>
>Saying it is up to the driver how to achieve a globally unique id across
>every different switch driver is really insufficient.  If I have two
>drivers that each implement an id that is 64bit long and they use two
>completely different methods there is a real chance of collision.
>
>So either I need a driver id that I also use in the comparison between
>switch ids or how a driver generates a globally unique id need to be
>specified.
>
>>>Right now switch id looks like one of those weird one manufacturer
>>>properties that is fine to expose as a driver specific property
>>>but I don't yet see it being a generic property I that can be used
>>>usefully in userspace.
>>>
>>>So can we please get some clear semantics or failing that can we please
>>>not expose this to userspace as generic property.
>>
>> I thought that the semantics is clean. Looks like I will have to update
>> Documentation/networking/switchdev.txt adding some more info about
>> this.
>
>The semantics as described so far will not achieve a useful id, which
>makes them rubbish.
>
>Eric

^ permalink raw reply

* Re: [PATCHv3 net] i40e: Implement ndo_gso_check()
From: Sergei Shtylyov @ 2014-12-04 19:11 UTC (permalink / raw)
  To: Joe Stringer, netdev
  Cc: linux-kernel, jesse, shannon.nelson, jesse.brandeburg,
	jeffrey.t.kirsher, therbert, linux.nics
In-Reply-To: <1417718366-14310-1-git-send-email-joestringer@nicira.com>

Hello.

On 12/04/2014 09:39 PM, Joe Stringer wrote:

> ndo_gso_check() was recently introduced to allow NICs to report the
> offloading support that they have on a per-skb basis. Add an
> implementation for this driver which checks for IPIP, GRE, UDP tunnels.

> Signed-off-by: Joe Stringer <joestringer@nicira.com>
> ---
> v3: Drop IPIP and GRE (no driver support even though hw supports it).
>      Check for UDP outer protocol for UDP tunnels.
> v2: Expand to include IP in IP and IPv4/IPv6 inside GRE/UDP tunnels.
>      Add MAX_INNER_LENGTH (as 80).
> ---
>   drivers/net/ethernet/intel/i40e/i40e_main.c |   26 ++++++++++++++++++++++++++
>   1 file changed, 26 insertions(+)

> diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
> index c3a7f4a..0d6493a 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_main.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
> @@ -7447,6 +7447,31 @@ static int i40e_ndo_fdb_dump(struct sk_buff *skb,
>
>   #endif /* USE_DEFAULT_FDB_DEL_DUMP */
>   #endif /* HAVE_FDB_OPS */

    Need empty line here, I think.

> +static bool i40e_gso_check(struct sk_buff *skb, struct net_device *dev)
> +{
> +	if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL) {
> +		unsigned char *ihdr;
> +
> +		if (skb->protocol != IPPROTO_UDP ||
> +		    skb->inner_protocol_type != ENCAP_TYPE_ETHER)
> +			return false;
> +
> +		if (skb->inner_protocol == htons(ETH_P_TEB))
> +			ihdr = skb_inner_mac_header(skb);
> +		else if (skb->inner_protocol == htons(ETH_P_IP) ||
> +			 skb->inner_protocol == htons(ETH_P_IPV6))
> +			ihdr = skb_inner_network_header(skb);
> +		else
> +			return false;

    The above is asking to be a *switch* instead, no?

> +
> +#define MAX_TUNNEL_HDR_LEN	80

    I'd #define this just above the function, if not at the start of the file...

[...]

WBR, Sergei

^ permalink raw reply

* Re: [patch iproute2 1/6] iproute2: ipa: show switch id
From: Eric W. Biederman @ 2014-12-04 18:57 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: netdev, davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse,
	pshelar, azhou, ben, stephen, jeffrey.t.kirsher, vyasevic,
	xiyou.wangcong, john.r.fastabend, edumazet, jhs, sfeldma,
	f.fainelli, roopa, linville, jasowang, nicolas.dichtel,
	ryazanov.s.a, buytenh, aviadr, nbd, alexei.starovoitov,
	Neil.Jerram, ronye, simon.horman, alexander.h.duyck, john.ronciak,
	mleitner, shrijeet, gospo, bcrl, hemal
In-Reply-To: <20141204182451.GI1861@nanopsycho.orion>

Jiri Pirko <jiri@resnulli.us> writes:

> Thu, Dec 04, 2014 at 06:52:49PM CET, ebiederm@xmission.com wrote:
>>Jiri Pirko <jiri@resnulli.us> writes:
>>
>>> Thu, Dec 04, 2014 at 05:15:04PM CET, ebiederm@xmission.com wrote:
>>>>Jiri Pirko <jiri@resnulli.us> writes:
>>>>
>>>>Would someone please explain to me what a switch id is?
>>>>
>>>>I looked in the kernel source, and I looked here and while I know
>>>>switches I don't have a clue what a switch id is.
>>>>
>>>>My primary concern at this point is that you have introduced a global
>>>>identifier that is isn't a hardware property (it certainly does not look
>>>>like a mac address) and that is unique across network namespaces and
>>>>thus breaks checkpoint/restart (aka CRIU).
>>>
>>> IFLA_PHYS_SWITCH_ID is very similar to IFLA_PHYS_PORT_ID. It is
>>> generated by the driver and ensures that there is the same switch id for
>>> all ports belonging to the same switch chip/asic. It is up to the driver
>>> how to implement the id. I would like to point you to driver
>>> implementing ndo_get_phys_port_id
>>
>>Looking at ndo_get_phys_port_id it is just the per port mac address.  Or
>>guid in the case of infiniband.  Which really makes me wonder why we
>>didn't use the same abstractions in the code for address types that we
>>do for hardware addresses.
>>
>>Using mac address or other hardware addresses that are used for layer 2
>>addressing makes sense to me.  There is a long tradition of that and as
>>I recall protocols like STP actually requiring having a different mac
>>address per port.
>>
>>When I asked the question I thought the switch id was going to be
>>something like the ifindex, the software index of a network device.
>>
>>
>>Finally having tracked down the rocker implementation of 
>>rocker_port_switch_parent_id_get I see it you are reading some 64bit
>>hardware register.
>>
>>Which leads me to ask what are the semantics of switch_id?
>>
>>Is the switch id an identifier with a prefix from IEEE and assigned by
>>the manufacture so that it is guaranteed to the tolerances of the
>>manufacturing process to be globally unique?
>
> It is up to the driver what to use. It can use mac addr. This is same as
> for phys port id.

My reading of the code says the phys port id is the layer 2 hardware
address of the port.  Certainly that is the case for all of the
implementations now and it would be insane for it to be anything else.

>>Is the switch id a random number that is statistically likely to be
>>globally unique because you have enough bits?   As I recall you need
>>at least 128 bits to have a reasonable chance of a random number
>>avoiding the birthday paradox.
>>
>>Do we need some kind of manufacturer id to tell one switch id from
>>another?
>>
>>Is the switch id persistent across reboots?
>
> Yes it is (as for phys port id).

>>>>Also what in the world does PHYS mean in IFLA_PHYS_SWITCH_ID?  Does that
>>>>mean we can't have a purely software implementation of this interface?
>>>>Given that we will want a software implementation at some point
>>>>including PHYS in the name seems completely wrong.
>>>
>>> We can remove the "PHYS", no problem. I do not understand what you say
>>> about "software implementation". The point is to allow hw switch/ish
>>> chips to be supported.
>>
>>If we are talking about something typically stored in a eeprom like a
>>mac address phys seems appropriate.
>
> Yes, we are.
>
>>
>>Still having a definition of this switch id clean clear enough that
>>net/bridge and drivers/net/macvlan can implement it seems important.
>
> I don't understand why would net/bridge or driver/net/macvlan want to
> implement this. The purpose is to group ports/netdevs which are part of
> the same hw switch.

Certainly all of the macvlan devices are part of the same logical
switch, and are all the same hardware.

>>Even more important is having a definition of switch id clear enough
>>that userspace can use the switch id to do something useful.
>
> Userspace threats this the same it treats phys port id.
>
> if two ports/netdevs has same switch id, they belong under same hw
> switch. That's all.

So this id needs to be globally unique?

How does the rocket driver achieve global uniquness?  Is the rocket
driver using an IEEE assigned prefix based id like the ethernet mac
address?

This is an important detail as ensuring global uniqueness can take a lot
of work so there needs to be a general agreement on how global
uniqueness is achieved.

Saying it is up to the driver how to achieve a globally unique id across
every different switch driver is really insufficient.  If I have two
drivers that each implement an id that is 64bit long and they use two
completely different methods there is a real chance of collision.

So either I need a driver id that I also use in the comparison between
switch ids or how a driver generates a globally unique id need to be
specified.

>>Right now switch id looks like one of those weird one manufacturer
>>properties that is fine to expose as a driver specific property
>>but I don't yet see it being a generic property I that can be used
>>usefully in userspace.
>>
>>So can we please get some clear semantics or failing that can we please
>>not expose this to userspace as generic property.
>
> I thought that the semantics is clean. Looks like I will have to update
> Documentation/networking/switchdev.txt adding some more info about
> this.

The semantics as described so far will not achieve a useful id, which
makes them rubbish.

Eric

^ permalink raw reply

* Re: [patch iproute2 5/6] link: add missing IFLA_BRPORT_PROXYARP
From: Stephen Hemminger @ 2014-12-04 18:53 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: netdev, davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse,
	pshelar, azhou, ben, jeffrey.t.kirsher, vyasevic, xiyou.wangcong,
	john.r.fastabend, edumazet, jhs, sfeldma, f.fainelli, roopa,
	linville, jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a,
	buytenh, aviadr, nbd, alexei.starovoitov, Neil.Jerram, ronye,
	simon.horman, alexander.h.duyck, john.ronciak, mleitner, shrijeet,
	gospo, bcrl, hemal
In-Reply-To: <1417683438-10935-6-git-send-email-jiri@resnulli.us>

On Thu,  4 Dec 2014 09:57:17 +0100
Jiri Pirko <jiri@resnulli.us> wrote:

> From: Scott Feldman <sfeldma@gmail.com>
> 
> Signed-off-by: Scott Feldman <sfeldma@gmail.com>
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
> ---
>  include/linux/if_link.h | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/include/linux/if_link.h b/include/linux/if_link.h
> index a6e2594..06efa2d 100644
> --- a/include/linux/if_link.h
> +++ b/include/linux/if_link.h
> @@ -242,6 +242,7 @@ enum {
>  	IFLA_BRPORT_FAST_LEAVE,	/* multicast fast leave    */
>  	IFLA_BRPORT_LEARNING,	/* mac learning */
>  	IFLA_BRPORT_UNICAST_FLOOD, /* flood unicast traffic */
> +	IFLA_BRPORT_PROXYARP,   /* proxy ARP */
>  	__IFLA_BRPORT_MAX
>  };
>  #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)

Unnecessary patch since I pick up headers from upstream.
Already on net-next branch.

^ permalink raw reply

* Re: [PATCHv3 net] i40e: Implement ndo_gso_check()
From: Jeff Kirsher @ 2014-12-04 18:46 UTC (permalink / raw)
  To: Joe Stringer
  Cc: netdev, linux-kernel, jesse, shannon.nelson, jesse.brandeburg,
	therbert, linux.nics
In-Reply-To: <1417718366-14310-1-git-send-email-joestringer@nicira.com>

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

On Thu, 2014-12-04 at 10:39 -0800, Joe Stringer wrote:
> ndo_gso_check() was recently introduced to allow NICs to report the
> offloading support that they have on a per-skb basis. Add an
> implementation for this driver which checks for IPIP, GRE, UDP
> tunnels.
> 
> Signed-off-by: Joe Stringer <joestringer@nicira.com>
> ---
> v3: Drop IPIP and GRE (no driver support even though hw supports it).
>     Check for UDP outer protocol for UDP tunnels.
> v2: Expand to include IP in IP and IPv4/IPv6 inside GRE/UDP tunnels.
>     Add MAX_INNER_LENGTH (as 80).
> ---
>  drivers/net/ethernet/intel/i40e/i40e_main.c |   26
> ++++++++++++++++++++++++++
>  1 file changed, 26 insertions(+)

Thanks Joe, I will add your patch to my queue.

Jesse Gross/Tom- If you guys are OK with the latest patch, I will move
forward with adding this patch to my queue.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply

* Re: [PATCHv2 net] i40e: Implement ndo_gso_check()
From: Joe Stringer @ 2014-12-04 18:41 UTC (permalink / raw)
  To: Jesse Gross
  Cc: Tom Herbert, netdev, Shannon Nelson, Brandeburg, Jesse,
	Jeff Kirsher, linux.nics, Linux Kernel Mailing List
In-Reply-To: <CAEP_g=9Yg-pZf9-Wb4qrZhAMSB=edqDxBXSRskWCturt-nnxTg@mail.gmail.com>

On 2 December 2014 at 10:26, Jesse Gross <jesse@nicira.com> wrote:
> On Mon, Dec 1, 2014 at 4:09 PM, Tom Herbert <therbert@google.com> wrote:
>> On Mon, Dec 1, 2014 at 3:53 PM, Jesse Gross <jesse@nicira.com> wrote:
>>> On Mon, Dec 1, 2014 at 3:47 PM, Tom Herbert <therbert@google.com> wrote:
>>>> On Mon, Dec 1, 2014 at 3:35 PM, Joe Stringer <joestringer@nicira.com> wrote:
>>>>> On 21 November 2014 at 09:59, Joe Stringer <joestringer@nicira.com> wrote:
>>>>>> On 20 November 2014 16:19, Jesse Gross <jesse@nicira.com> wrote:
>>>>>>> I don't know if we need to have the check at all for IPIP though -
>>>>>>> after all the driver doesn't expose support for it all (actually it
>>>>>>> doesn't expose GRE either). This raises kind of an interesting
>>>>>>> question about the checks though - it's pretty easy to add support to
>>>>>>> the driver for a new GSO type (and I imagine that people will be
>>>>>>> adding GRE soon) and forget to update the check.
>>>>>>
>>>>>> If the check is more conservative, then testing would show that it's
>>>>>> not working and lead people to figure out why (and update the check).
>>>>>
>>>>> More concretely, one suggestion would be something like following at
>>>>> the start of each gso_check():
>>>>>
>>>>> +       const int supported = SKB_GSO_TCPV4 | SKB_GSO_TCPV6 | SKB_GSO_FCOE |
>>>>> +                             SKB_GSO_UDP | SKB_GSO_UDP_TUNNEL;
>>>>> +
>>>>> +       if (skb_shinfo(skb)->gso_type & ~supported)
>>>>> +               return false;
>>>>
>>>> This should already be handled by net_gso_ok.
>>>
>>> My original point wasn't so much that this isn't handled at the moment
>>> but that it's easy to add a supported GSO type but then forget to
>>> update this check - i.e. if a driver already supports UDP_TUNNEL and
>>> adds support for GRE with the same constraints. It seems not entirely
>>> ideal that this function is acting as a blacklist rather than a
>>> whitelist.
>>
>> Agreed, it would be nice to have all the checking logic in one place.
>> If all the drivers end up implementing ndo_gso_check then we could
>> potentially get rid of the GSO types as features. This probably
>> wouldn't be a bad thing since we already know that the features
>> mechanism doesn't scale (for instance there's no way to indicate that
>> certain combinations of GSO types are supported by a device).
>
> This crossed my mind and I agree that it's pretty clear that the
> features mechanism isn't scaling very well. Presumably, the logical
> extension of this is that each driver would have a function that looks
> at a packet and returns a set of offload operations that it can
> support rather than exposing a set of protocols. However, it seems
> like it would probably result in a bunch of duplicate code in each
> driver.

Given the discussion is still pretty open-ended, I've made the basic
feedback changes for v3 and haven't tried to address the concern about
forgetting to update this check when a driver adds support.

^ permalink raw reply

* [PATCHv3 net] i40e: Implement ndo_gso_check()
From: Joe Stringer @ 2014-12-04 18:39 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, jesse, shannon.nelson, jesse.brandeburg,
	jeffrey.t.kirsher, therbert, linux.nics

ndo_gso_check() was recently introduced to allow NICs to report the
offloading support that they have on a per-skb basis. Add an
implementation for this driver which checks for IPIP, GRE, UDP tunnels.

Signed-off-by: Joe Stringer <joestringer@nicira.com>
---
v3: Drop IPIP and GRE (no driver support even though hw supports it).
    Check for UDP outer protocol for UDP tunnels.
v2: Expand to include IP in IP and IPv4/IPv6 inside GRE/UDP tunnels.
    Add MAX_INNER_LENGTH (as 80).
---
 drivers/net/ethernet/intel/i40e/i40e_main.c |   26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index c3a7f4a..0d6493a 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -7447,6 +7447,31 @@ static int i40e_ndo_fdb_dump(struct sk_buff *skb,
 
 #endif /* USE_DEFAULT_FDB_DEL_DUMP */
 #endif /* HAVE_FDB_OPS */
+static bool i40e_gso_check(struct sk_buff *skb, struct net_device *dev)
+{
+	if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL) {
+		unsigned char *ihdr;
+
+		if (skb->protocol != IPPROTO_UDP ||
+		    skb->inner_protocol_type != ENCAP_TYPE_ETHER)
+			return false;
+
+		if (skb->inner_protocol == htons(ETH_P_TEB))
+			ihdr = skb_inner_mac_header(skb);
+		else if (skb->inner_protocol == htons(ETH_P_IP) ||
+			 skb->inner_protocol == htons(ETH_P_IPV6))
+			ihdr = skb_inner_network_header(skb);
+		else
+			return false;
+
+#define MAX_TUNNEL_HDR_LEN	80
+		if (ihdr - skb_transport_header(skb) > MAX_TUNNEL_HDR_LEN)
+			return false;
+	}
+
+	return true;
+}
+
 static const struct net_device_ops i40e_netdev_ops = {
 	.ndo_open		= i40e_open,
 	.ndo_stop		= i40e_close,
@@ -7487,6 +7512,7 @@ static const struct net_device_ops i40e_netdev_ops = {
 	.ndo_fdb_dump		= i40e_ndo_fdb_dump,
 #endif
 #endif
+	.ndo_gso_check		= i40e_gso_check,
 };
 
 /**
-- 
1.7.10.4

^ permalink raw reply related

* Re: [patch iproute2 1/6] iproute2: ipa: show switch id
From: Jiri Pirko @ 2014-12-04 18:24 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: netdev, davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse,
	pshelar, azhou, ben, stephen, jeffrey.t.kirsher, vyasevic,
	xiyou.wangcong, john.r.fastabend, edumazet, jhs, sfeldma,
	f.fainelli, roopa, linville, jasowang, nicolas.dichtel,
	ryazanov.s.a, buytenh, aviadr, nbd, alexei.starovoitov,
	Neil.Jerram, ronye, simon.horman, alexander.h.duyck, john.ronciak,
	mleitner, shrijeet, gospo, bcrl, hemal
In-Reply-To: <87388v9ua6.fsf@x220.int.ebiederm.org>

Thu, Dec 04, 2014 at 06:52:49PM CET, ebiederm@xmission.com wrote:
>Jiri Pirko <jiri@resnulli.us> writes:
>
>> Thu, Dec 04, 2014 at 05:15:04PM CET, ebiederm@xmission.com wrote:
>>>Jiri Pirko <jiri@resnulli.us> writes:
>>>
>>>Would someone please explain to me what a switch id is?
>>>
>>>I looked in the kernel source, and I looked here and while I know
>>>switches I don't have a clue what a switch id is.
>>>
>>>My primary concern at this point is that you have introduced a global
>>>identifier that is isn't a hardware property (it certainly does not look
>>>like a mac address) and that is unique across network namespaces and
>>>thus breaks checkpoint/restart (aka CRIU).
>>
>> IFLA_PHYS_SWITCH_ID is very similar to IFLA_PHYS_PORT_ID. It is
>> generated by the driver and ensures that there is the same switch id for
>> all ports belonging to the same switch chip/asic. It is up to the driver
>> how to implement the id. I would like to point you to driver
>> implementing ndo_get_phys_port_id
>
>Looking at ndo_get_phys_port_id it is just the per port mac address.  Or
>guid in the case of infiniband.  Which really makes me wonder why we
>didn't use the same abstractions in the code for address types that we
>do for hardware addresses.
>
>Using mac address or other hardware addresses that are used for layer 2
>addressing makes sense to me.  There is a long tradition of that and as
>I recall protocols like STP actually requiring having a different mac
>address per port.
>
>When I asked the question I thought the switch id was going to be
>something like the ifindex, the software index of a network device.
>
>
>Finally having tracked down the rocker implementation of 
>rocker_port_switch_parent_id_get I see it you are reading some 64bit
>hardware register.
>
>Which leads me to ask what are the semantics of switch_id?
>
>Is the switch id an identifier with a prefix from IEEE and assigned by
>the manufacture so that it is guaranteed to the tolerances of the
>manufacturing process to be globally unique?

It is up to the driver what to use. It can use mac addr. This is same as
for phys port id.


>
>Is the switch id a random number that is statistically likely to be
>globally unique because you have enough bits?   As I recall you need
>at least 128 bits to have a reasonable chance of a random number
>avoiding the birthday paradox.
>
>Do we need some kind of manufacturer id to tell one switch id from
>another?
>
>Is the switch id persistent across reboots?

Yes it is (as for phys port id).

>
>>>Also what in the world does PHYS mean in IFLA_PHYS_SWITCH_ID?  Does that
>>>mean we can't have a purely software implementation of this interface?
>>>Given that we will want a software implementation at some point
>>>including PHYS in the name seems completely wrong.
>>
>> We can remove the "PHYS", no problem. I do not understand what you say
>> about "software implementation". The point is to allow hw switch/ish
>> chips to be supported.
>
>If we are talking about something typically stored in a eeprom like a
>mac address phys seems appropriate.

Yes, we are.

>
>Still having a definition of this switch id clean clear enough that
>net/bridge and drivers/net/macvlan can implement it seems important.

I don't understand why would net/bridge or driver/net/macvlan want to
implement this. The purpose is to group ports/netdevs which are part of
the same hw switch.

>
>Even more important is having a definition of switch id clear enough
>that userspace can use the switch id to do something useful.

Userspace threats this the same it treats phys port id.

if two ports/netdevs has same switch id, they belong under same hw
switch. That's all.


>
>Right now switch id looks like one of those weird one manufacturer
>properties that is fine to expose as a driver specific property
>but I don't yet see it being a generic property I that can be used
>usefully in userspace.
>
>So can we please get some clear semantics or failing that can we please
>not expose this to userspace as generic property.

I thought that the semantics is clean. Looks like I will have to update
Documentation/networking/switchdev.txt adding some more info about this.

>
>Thanks,
>Eric
>
>
>
>>>> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
>>>> ---
>>>>  include/linux/if_link.h | 1 +
>>>>  ip/ipaddress.c          | 8 ++++++++
>>>>  2 files changed, 9 insertions(+)
>>>>
>>>> diff --git a/include/linux/if_link.h b/include/linux/if_link.h
>>>> index 4732063..a6e2594 100644
>>>> --- a/include/linux/if_link.h
>>>> +++ b/include/linux/if_link.h
>>>> @@ -145,6 +145,7 @@ enum {
>>>>  	IFLA_CARRIER,
>>>>  	IFLA_PHYS_PORT_ID,
>>>>  	IFLA_CARRIER_CHANGES,
>>>> +	IFLA_PHYS_SWITCH_ID,
>>>>  	__IFLA_MAX
>>>>  };
>>>>  
>>>> diff --git a/ip/ipaddress.c b/ip/ipaddress.c
>>>> index 4d99324..bd36a07 100644
>>>> --- a/ip/ipaddress.c
>>>> +++ b/ip/ipaddress.c
>>>> @@ -589,6 +589,14 @@ int print_linkinfo(const struct sockaddr_nl *who,
>>>>  				      b1, sizeof(b1)));
>>>>  	}
>>>>  
>>>> +	if (tb[IFLA_PHYS_SWITCH_ID]) {
>>>> +		SPRINT_BUF(b1);
>>>> +		fprintf(fp, "switchid %s ",
>>>> +			hexstring_n2a(RTA_DATA(tb[IFLA_PHYS_SWITCH_ID]),
>>>> +				      RTA_PAYLOAD(tb[IFLA_PHYS_SWITCH_ID]),
>>>> +				      b1, sizeof(b1)));
>>>> +	}
>>>> +
>>>>  	if (tb[IFLA_OPERSTATE])
>>>>  		print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE]));

^ permalink raw reply

* Re: [PATCH] net: ethernet: rocker: Add select to CONFIG_BRIDGE in Kconfig
From: Jiri Pirko @ 2014-12-04 18:15 UTC (permalink / raw)
  To: Andreas Ruprecht
  Cc: Jim Davis, Stephen Rothwell, linux-next, linux-kernel, sfeldma,
	netdev
In-Reply-To: <54809BA5.7030901@rupran.de>

Thu, Dec 04, 2014 at 06:36:37PM CET, mail@rupran.de wrote:
>On 04.12.2014 17:34, Jim Davis wrote:
>> Building with the attached random configuration file,
>> 
>> drivers/built-in.o: In function `rocker_port_fdb_learn_work':
>> /home/jim/linux/drivers/net/ethernet/rocker/rocker.c:3014: undefined
>> reference to `br_fdb_external_learn_del'
>> /home/jim/linux/drivers/net/ethernet/rocker/rocker.c:3016: undefined
>> reference to `br_fdb_external_learn_add'
>> 
>
>Hi,
>
>the problem here is that CONFIG_BRIDGE is set to 'm' (leading to
>inclusion of the two functions above in the kernel module) while
>CONFIG_ROCKER is set to 'y', requiring the functions at link time.
>
>Is the attached patch sufficient to fix this?
>
>Regards,
>
>Andreas

>From 0529c3cbe381338dc3337e07a71e15b3d22a3255 Mon Sep 17 00:00:00 2001
>From: Andreas Ruprecht <rupran@einserver.de>
>Date: Thu, 4 Dec 2014 18:28:09 +0100
>Subject: [PATCH] net: ethernet: rocker: Add select to CONFIG_BRIDGE in Kconfig
>
>In a configuration with CONFIG_BRIDGE set to 'm' and CONFIG_ROCKER
>set to 'y', undefined references occur at link time:
>
>> drivers/built-in.o: In function `rocker_port_fdb_learn_work':
>> /home/jim/linux/drivers/net/ethernet/rocker/rocker.c:3014: undefined
>> reference to `br_fdb_external_learn_del'
>> /home/jim/linux/drivers/net/ethernet/rocker/rocker.c:3016: undefined
>> reference to `br_fdb_external_learn_add'
>
>This patch fixes these by selecting CONFIG_BRIDGE from CONFIG_ROCKER.
>
>Reported-by: Jim Davis <jim.epost@gmail.com>
>Signed-off-by: Andreas Ruprecht <rupran@einserver.de>
Acked-by: Jiri Pirko <jiri@resnulli.us>

this is ok for now. There is a plan to replace
br_fdb_external_learn_add/del a by notifier which will fix this as well.

Thanks.

>---
> drivers/net/ethernet/rocker/Kconfig | 1 +
> 1 file changed, 1 insertion(+)
>
>diff --git a/drivers/net/ethernet/rocker/Kconfig b/drivers/net/ethernet/rocker/Kconfig
>index 11a850eab628..ade10ec4c78d 100644
>--- a/drivers/net/ethernet/rocker/Kconfig
>+++ b/drivers/net/ethernet/rocker/Kconfig
>@@ -18,6 +18,7 @@ if NET_VENDOR_ROCKER
> config ROCKER
> 	tristate "Rocker switch driver (EXPERIMENTAL)"
> 	depends on PCI && NET_SWITCHDEV
>+	select BRIDGE
> 	---help---
> 	  This driver supports Rocker switch device.
> 
>-- 
>1.9.1
>

^ permalink raw reply

* Re: [PATCH] x86: bpf_jit_comp: simplify trivial boolean return
From: Joe Perches @ 2014-12-04 18:05 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: David Laight, Quentin Lambert, David S. Miller, Alexey Kuznetsov,
	James Morris, Hideaki YOSHIFUJI, Patrick McHardy, Thomas Gleixner,
	Ingo Molnar, H. Peter Anvin, x86@kernel.org,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <CAADnVQJawht6+sARaP=s9PyPERjrVOBKiJLrCK0OwnLtzT2CAA@mail.gmail.com>

On Thu, 2014-12-04 at 07:56 -0800, Alexei Starovoitov wrote:
> On Thu, Dec 4, 2014 at 1:26 AM, Joe Perches <joe@perches.com> wrote:
> > On Thu, 2014-11-27 at 10:49 -0800, Joe Perches wrote:
> >> On Thu, 2014-11-27 at 12:25 +0000, David Laight wrote:
> >> > Why the change in data?
> >>
> >> btw: without gcov and using -O2
> >>
> >> $ size arch/x86/net/bpf_jit_comp.o*
> >>    text          data     bss     dec     hex filename
> >>    9671             4       0    9675    25cb arch/x86/net/bpf_jit_comp.o.new
> >>   10679             4       0   10683    29bb arch/x86/net/bpf_jit_comp.o.old
> >
> > Alexei?
> >
> > Is this 10% reduction in size a good reason to change the code?
> 
> yes.
> I believe you're seeing it with gcc 4.9. I wanted to double
> check what 4.6 and 4.7 are doing. If they're not suddenly
> increase code size then resubmit it for inclusion please.

I get these sizes for these compilers
(x86-64, -O2, without profiling)

$ size arch/x86/net/bpf_jit_comp.o*
   text	   data	    bss	    dec	    hex	filename
   9266	      4	      0	   9270	   2436	arch/x86/net/bpf_jit_comp.o.4.4.new
  10042	      4	      0	  10046	   273e	arch/x86/net/bpf_jit_comp.o.4.4.old
   9109	      4	      0	   9113	   2399	arch/x86/net/bpf_jit_comp.o.4.6.new
   9717	      4	      0	   9721	   25f9	arch/x86/net/bpf_jit_comp.o.4.6.old
   8789	      4	      0	   8793	   2259	arch/x86/net/bpf_jit_comp.o.4.7.new
  10245	      4	      0	  10249	   2809	arch/x86/net/bpf_jit_comp.o.4.7.old
   9671	      4	      0	   9675	   25cb	arch/x86/net/bpf_jit_comp.o.4.9.new
  10679	      4	      0	  10683	   29bb	arch/x86/net/bpf_jit_comp.o.4.9.old

I am a bit surprised by the size variations

^ permalink raw reply

* Re: [patch iproute2 1/6] iproute2: ipa: show switch id
From: Roopa Prabhu @ 2014-12-04 17:59 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: Jiri Pirko, netdev, davem, nhorman, andy, tgraf, dborkman,
	ogerlitz, jesse, pshelar, azhou, ben, stephen, jeffrey.t.kirsher,
	vyasevic, xiyou.wangcong, john.r.fastabend, edumazet, jhs,
	sfeldma, f.fainelli, linville, jasowang, nicolas.dichtel,
	ryazanov.s.a, buytenh, aviadr, nbd, alexei.starovoitov,
	Neil.Jerram, ronye, simon.horman, alexander.h.duyck, john.ronciak,
	mleitner, shrijeet, gospo, bcrl, hemal
In-Reply-To: <87388v9ua6.fsf@x220.int.ebiederm.org>

On 12/4/14, 9:52 AM, Eric W. Biederman wrote:
> Jiri Pirko <jiri@resnulli.us> writes:
>
>> Thu, Dec 04, 2014 at 05:15:04PM CET, ebiederm@xmission.com wrote:
>>> Jiri Pirko <jiri@resnulli.us> writes:
>>>
>>> Would someone please explain to me what a switch id is?
>>>
>>> I looked in the kernel source, and I looked here and while I know
>>> switches I don't have a clue what a switch id is.
>>>
>>> My primary concern at this point is that you have introduced a global
>>> identifier that is isn't a hardware property (it certainly does not look
>>> like a mac address) and that is unique across network namespaces and
>>> thus breaks checkpoint/restart (aka CRIU).
>> IFLA_PHYS_SWITCH_ID is very similar to IFLA_PHYS_PORT_ID. It is
>> generated by the driver and ensures that there is the same switch id for
>> all ports belonging to the same switch chip/asic. It is up to the driver
>> how to implement the id. I would like to point you to driver
>> implementing ndo_get_phys_port_id
> Looking at ndo_get_phys_port_id it is just the per port mac address.  Or
> guid in the case of infiniband.  Which really makes me wonder why we
> didn't use the same abstractions in the code for address types that we
> do for hardware addresses.
>
> Using mac address or other hardware addresses that are used for layer 2
> addressing makes sense to me.  There is a long tradition of that and as
> I recall protocols like STP actually requiring having a different mac
> address per port.
>
> When I asked the question I thought the switch id was going to be
> something like the ifindex, the software index of a network device.
>
>
> Finally having tracked down the rocker implementation of
> rocker_port_switch_parent_id_get I see it you are reading some 64bit
> hardware register.
>
> Which leads me to ask what are the semantics of switch_id?
>
> Is the switch id an identifier with a prefix from IEEE and assigned by
> the manufacture so that it is guaranteed to the tolerances of the
> manufacturing process to be globally unique?
>
> Is the switch id a random number that is statistically likely to be
> globally unique because you have enough bits?   As I recall you need
> at least 128 bits to have a reasonable chance of a random number
> avoiding the birthday paradox.
>
> Do we need some kind of manufacturer id to tell one switch id from
> another?
>
> Is the switch id persistent across reboots?
>
>>> Also what in the world does PHYS mean in IFLA_PHYS_SWITCH_ID?  Does that
>>> mean we can't have a purely software implementation of this interface?
>>> Given that we will want a software implementation at some point
>>> including PHYS in the name seems completely wrong.
>> We can remove the "PHYS", no problem. I do not understand what you say
>> about "software implementation". The point is to allow hw switch/ish
>> chips to be supported.
> If we are talking about something typically stored in a eeprom like a
> mac address phys seems appropriate.
>
> Still having a definition of this switch id clean clear enough that
> net/bridge and drivers/net/macvlan can implement it seems important.
>
> Even more important is having a definition of switch id clear enough
> that userspace can use the switch id to do something useful.
>
> Right now switch id looks like one of those weird one manufacturer
> properties that is fine to expose as a driver specific property
> but I don't yet see it being a generic property I that can be used
> usefully in userspace.
>
> So can we please get some clear semantics or failing that can we please
> not expose this to userspace as generic property.

Agree..100%. This was my original concern as well and i have raised it 
earlier.
  Don't expose it to userspace if the semantics are still not clear.

Thanks.

>>>> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
>>>> ---
>>>>   include/linux/if_link.h | 1 +
>>>>   ip/ipaddress.c          | 8 ++++++++
>>>>   2 files changed, 9 insertions(+)
>>>>
>>>> diff --git a/include/linux/if_link.h b/include/linux/if_link.h
>>>> index 4732063..a6e2594 100644
>>>> --- a/include/linux/if_link.h
>>>> +++ b/include/linux/if_link.h
>>>> @@ -145,6 +145,7 @@ enum {
>>>>   	IFLA_CARRIER,
>>>>   	IFLA_PHYS_PORT_ID,
>>>>   	IFLA_CARRIER_CHANGES,
>>>> +	IFLA_PHYS_SWITCH_ID,
>>>>   	__IFLA_MAX
>>>>   };
>>>>   
>>>> diff --git a/ip/ipaddress.c b/ip/ipaddress.c
>>>> index 4d99324..bd36a07 100644
>>>> --- a/ip/ipaddress.c
>>>> +++ b/ip/ipaddress.c
>>>> @@ -589,6 +589,14 @@ int print_linkinfo(const struct sockaddr_nl *who,
>>>>   				      b1, sizeof(b1)));
>>>>   	}
>>>>   
>>>> +	if (tb[IFLA_PHYS_SWITCH_ID]) {
>>>> +		SPRINT_BUF(b1);
>>>> +		fprintf(fp, "switchid %s ",
>>>> +			hexstring_n2a(RTA_DATA(tb[IFLA_PHYS_SWITCH_ID]),
>>>> +				      RTA_PAYLOAD(tb[IFLA_PHYS_SWITCH_ID]),
>>>> +				      b1, sizeof(b1)));
>>>> +	}
>>>> +
>>>>   	if (tb[IFLA_OPERSTATE])
>>>>   		print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE]));

^ permalink raw reply

* Re: [patch iproute2 1/6] iproute2: ipa: show switch id
From: Eric W. Biederman @ 2014-12-04 17:52 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: netdev, davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse,
	pshelar, azhou, ben, stephen, jeffrey.t.kirsher, vyasevic,
	xiyou.wangcong, john.r.fastabend, edumazet, jhs, sfeldma,
	f.fainelli, roopa, linville, jasowang, nicolas.dichtel,
	ryazanov.s.a, buytenh, aviadr, nbd, alexei.starovoitov,
	Neil.Jerram, ronye, simon.horman, alexander.h.duyck, john.ronciak,
	mleitner, shrijeet, gospo, bcrl, hemal
In-Reply-To: <20141204163024.GG1861@nanopsycho.orion>

Jiri Pirko <jiri@resnulli.us> writes:

> Thu, Dec 04, 2014 at 05:15:04PM CET, ebiederm@xmission.com wrote:
>>Jiri Pirko <jiri@resnulli.us> writes:
>>
>>Would someone please explain to me what a switch id is?
>>
>>I looked in the kernel source, and I looked here and while I know
>>switches I don't have a clue what a switch id is.
>>
>>My primary concern at this point is that you have introduced a global
>>identifier that is isn't a hardware property (it certainly does not look
>>like a mac address) and that is unique across network namespaces and
>>thus breaks checkpoint/restart (aka CRIU).
>
> IFLA_PHYS_SWITCH_ID is very similar to IFLA_PHYS_PORT_ID. It is
> generated by the driver and ensures that there is the same switch id for
> all ports belonging to the same switch chip/asic. It is up to the driver
> how to implement the id. I would like to point you to driver
> implementing ndo_get_phys_port_id

Looking at ndo_get_phys_port_id it is just the per port mac address.  Or
guid in the case of infiniband.  Which really makes me wonder why we
didn't use the same abstractions in the code for address types that we
do for hardware addresses.

Using mac address or other hardware addresses that are used for layer 2
addressing makes sense to me.  There is a long tradition of that and as
I recall protocols like STP actually requiring having a different mac
address per port.

When I asked the question I thought the switch id was going to be
something like the ifindex, the software index of a network device.


Finally having tracked down the rocker implementation of 
rocker_port_switch_parent_id_get I see it you are reading some 64bit
hardware register.

Which leads me to ask what are the semantics of switch_id?

Is the switch id an identifier with a prefix from IEEE and assigned by
the manufacture so that it is guaranteed to the tolerances of the
manufacturing process to be globally unique?

Is the switch id a random number that is statistically likely to be
globally unique because you have enough bits?   As I recall you need
at least 128 bits to have a reasonable chance of a random number
avoiding the birthday paradox.

Do we need some kind of manufacturer id to tell one switch id from
another?

Is the switch id persistent across reboots?

>>Also what in the world does PHYS mean in IFLA_PHYS_SWITCH_ID?  Does that
>>mean we can't have a purely software implementation of this interface?
>>Given that we will want a software implementation at some point
>>including PHYS in the name seems completely wrong.
>
> We can remove the "PHYS", no problem. I do not understand what you say
> about "software implementation". The point is to allow hw switch/ish
> chips to be supported.

If we are talking about something typically stored in a eeprom like a
mac address phys seems appropriate.

Still having a definition of this switch id clean clear enough that
net/bridge and drivers/net/macvlan can implement it seems important.

Even more important is having a definition of switch id clear enough
that userspace can use the switch id to do something useful.

Right now switch id looks like one of those weird one manufacturer
properties that is fine to expose as a driver specific property
but I don't yet see it being a generic property I that can be used
usefully in userspace.

So can we please get some clear semantics or failing that can we please
not expose this to userspace as generic property.

Thanks,
Eric



>>> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
>>> ---
>>>  include/linux/if_link.h | 1 +
>>>  ip/ipaddress.c          | 8 ++++++++
>>>  2 files changed, 9 insertions(+)
>>>
>>> diff --git a/include/linux/if_link.h b/include/linux/if_link.h
>>> index 4732063..a6e2594 100644
>>> --- a/include/linux/if_link.h
>>> +++ b/include/linux/if_link.h
>>> @@ -145,6 +145,7 @@ enum {
>>>  	IFLA_CARRIER,
>>>  	IFLA_PHYS_PORT_ID,
>>>  	IFLA_CARRIER_CHANGES,
>>> +	IFLA_PHYS_SWITCH_ID,
>>>  	__IFLA_MAX
>>>  };
>>>  
>>> diff --git a/ip/ipaddress.c b/ip/ipaddress.c
>>> index 4d99324..bd36a07 100644
>>> --- a/ip/ipaddress.c
>>> +++ b/ip/ipaddress.c
>>> @@ -589,6 +589,14 @@ int print_linkinfo(const struct sockaddr_nl *who,
>>>  				      b1, sizeof(b1)));
>>>  	}
>>>  
>>> +	if (tb[IFLA_PHYS_SWITCH_ID]) {
>>> +		SPRINT_BUF(b1);
>>> +		fprintf(fp, "switchid %s ",
>>> +			hexstring_n2a(RTA_DATA(tb[IFLA_PHYS_SWITCH_ID]),
>>> +				      RTA_PAYLOAD(tb[IFLA_PHYS_SWITCH_ID]),
>>> +				      b1, sizeof(b1)));
>>> +	}
>>> +
>>>  	if (tb[IFLA_OPERSTATE])
>>>  		print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE]));

^ permalink raw reply

* [PATCH net] amd-xgbe: Prevent Tx cleanup stall
From: Tom Lendacky @ 2014-12-04 17:52 UTC (permalink / raw)
  To: netdev; +Cc: David Miller

When performing Tx cleanup, the dirty index counter is compared to the
current index counter as one of the tests used to determine when to stop
cleanup. The "less than" test will fail when the current index counter
rolls over to zero causing cleanup to never occur again. Update the test
to a "not equal" to avoid this situation.

Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
 drivers/net/ethernet/amd/xgbe/xgbe-drv.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index 2349ea9..d0e3530 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -1554,7 +1554,7 @@ static int xgbe_tx_poll(struct xgbe_channel *channel)
 	spin_lock_irqsave(&ring->lock, flags);
 
 	while ((processed < XGBE_TX_DESC_MAX_PROC) &&
-	       (ring->dirty < ring->cur)) {
+	       (ring->dirty != ring->cur)) {
 		rdata = XGBE_GET_DESC_DATA(ring, ring->dirty);
 		rdesc = rdata->rdesc;
 

^ permalink raw reply related

* [PATCH v6 7/7] fs/splice: full support for compiling out splice
From: Pieter Smith @ 2014-12-04 17:50 UTC (permalink / raw)
  To: linux-kernel
  Cc: Josh Triplett, Pieter Smith, Alexander Duyck, Alexander Viro,
	Alexei Starovoitov, Andrew Morton, Bertrand Jacquin,
	Catalina Mocanu, Daniel Borkmann, David S. Miller, Eric Dumazet,
	Eric W. Biederman, Fabian Frederick,
	open list:FUSE: FILESYSTEM..., Geert Uytterhoeven, Hugh Dickins,
	Iulia Manda, Jan Beulich, J. Bruce Fields, Jeff Layton,
	open list:ABI/API, linux-fsd
In-Reply-To: <1417715473-24110-1-git-send-email-pieter@boesman.nl>

Entirely compile out splice translation unit when the system is configured
without splice family of syscalls (i.e. CONFIG_SYSCALL_SPLICE is undefined).

Exported fs/splice functions are transparently mocked out with static inlines.
Because userspace support for splice has already been removed by this
patch-set, the exported functions cannot be called anyway. Mocking them out
prevents a maintenance burden on file system drivers.

The bloat score resulting from this patch given a tinyconfig is:
add/remove: 0/25 grow/shrink: 0/5 up/down: 0/-4845 (-4845)
function                                     old     new   delta
pipe_to_null                                   4       -      -4
generic_pipe_buf_nosteal                       6       -      -6
spd_release_page                              10       -     -10
PageUptodate                                  22      11     -11
lock_page                                     36      24     -12
page_cache_pipe_buf_release                   16       -     -16
splice_write_null                             24       4     -20
page_cache_pipe_buf_ops                       20       -     -20
nosteal_pipe_buf_ops                          20       -     -20
default_pipe_buf_ops                          20       -     -20
generic_splice_sendpage                       24       -     -24
splice_shrink_spd                             27       -     -27
direct_splice_actor                           47       -     -47
default_file_splice_write                     49       -     -49
wakeup_pipe_writers                           54       -     -54
write_pipe_buf                                71       -     -71
page_cache_pipe_buf_confirm                   80       -     -80
splice_grow_spd                               87       -     -87
splice_from_pipe                              93       -     -93
splice_from_pipe_next                        106       -    -106
pipe_to_sendpage                             109       -    -109
page_cache_pipe_buf_steal                    114       -    -114
generic_file_splice_read                     131       8    -123
do_splice_direct                             148       -    -148
__splice_from_pipe                           246       -    -246
splice_direct_to_actor                       416       -    -416
splice_to_pipe                               417       -    -417
default_file_splice_read                     688       -    -688
iter_file_splice_write                       702       4    -698
__generic_file_splice_read                  1109       -   -1109

The bloat score for the entire CONFIG_SYSCALL_SPLICE patch-set is:
add/remove: 0/41 grow/shrink: 5/7 up/down: 23/-8422 (-8399)
function                                     old     new   delta
sys_pwritev                                  115     122      +7
sys_preadv                                   115     122      +7
fdput_pos                                     29      36      +7
sys_pwrite64                                 115     116      +1
sys_pread64                                  115     116      +1
pipe_to_null                                   4       -      -4
generic_pipe_buf_nosteal                       6       -      -6
spd_release_page                              10       -     -10
fdput                                         11       -     -11
PageUptodate                                  22      11     -11
lock_page                                     36      24     -12
signal_pending                                39      26     -13
fdget                                         56      42     -14
page_cache_pipe_buf_release                   16       -     -16
user_page_pipe_buf_ops                        20       -     -20
splice_write_null                             24       4     -20
page_cache_pipe_buf_ops                       20       -     -20
nosteal_pipe_buf_ops                          20       -     -20
default_pipe_buf_ops                          20       -     -20
generic_splice_sendpage                       24       -     -24
user_page_pipe_buf_steal                      25       -     -25
splice_shrink_spd                             27       -     -27
pipe_to_user                                  43       -     -43
direct_splice_actor                           47       -     -47
default_file_splice_write                     49       -     -49
wakeup_pipe_writers                           54       -     -54
wakeup_pipe_readers                           54       -     -54
write_pipe_buf                                71       -     -71
page_cache_pipe_buf_confirm                   80       -     -80
splice_grow_spd                               87       -     -87
do_splice_to                                  87       -     -87
ipipe_prep.part                               92       -     -92
splice_from_pipe                              93       -     -93
splice_from_pipe_next                        107       -    -107
pipe_to_sendpage                             109       -    -109
page_cache_pipe_buf_steal                    114       -    -114
opipe_prep.part                              119       -    -119
sys_sendfile                                 122       -    -122
generic_file_splice_read                     131       8    -123
sys_sendfile64                               126       -    -126
sys_vmsplice                                 137       -    -137
do_splice_direct                             148       -    -148
vmsplice_to_user                             205       -    -205
__splice_from_pipe                           246       -    -246
splice_direct_to_actor                       348       -    -348
splice_to_pipe                               371       -    -371
do_sendfile                                  492       -    -492
sys_tee                                      497       -    -497
vmsplice_to_pipe                             558       -    -558
default_file_splice_read                     688       -    -688
iter_file_splice_write                       702       4    -698
sys_splice                                  1075       -   -1075
__generic_file_splice_read                  1109       -   -1109

Signed-off-by: Pieter Smith <pieter@boesman.nl>
---
 fs/Makefile            |  3 ++-
 fs/splice.c            |  2 --
 include/linux/fs.h     | 26 ++++++++++++++++++++++++++
 include/linux/splice.h | 42 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 70 insertions(+), 3 deletions(-)

diff --git a/fs/Makefile b/fs/Makefile
index fb7646e..9395622 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -10,7 +10,7 @@ obj-y :=	open.o read_write.o file_table.o super.o \
 		ioctl.o readdir.o select.o dcache.o inode.o \
 		attr.o bad_inode.o file.o filesystems.o namespace.o \
 		seq_file.o xattr.o libfs.o fs-writeback.o \
-		pnode.o splice.o sync.o utimes.o \
+		pnode.o sync.o utimes.o \
 		stack.o fs_struct.o statfs.o fs_pin.o
 
 ifeq ($(CONFIG_BLOCK),y)
@@ -22,6 +22,7 @@ endif
 obj-$(CONFIG_PROC_FS) += proc_namespace.o
 
 obj-$(CONFIG_FSNOTIFY)		+= notify/
+obj-$(CONFIG_SYSCALL_SPLICE)	+= splice.o
 obj-$(CONFIG_EPOLL)		+= eventpoll.o
 obj-$(CONFIG_ANON_INODES)	+= anon_inodes.o
 obj-$(CONFIG_SIGNALFD)		+= signalfd.o
diff --git a/fs/splice.c b/fs/splice.c
index 7c4c695..44b201b 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -1316,7 +1316,6 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
 	return ret;
 }
 
-#ifdef CONFIG_SYSCALL_SPLICE
 static int splice_pipe_to_pipe(struct pipe_inode_info *ipipe,
 			       struct pipe_inode_info *opipe,
 			       size_t len, unsigned int flags);
@@ -2201,5 +2200,4 @@ COMPAT_SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd,
 	return do_sendfile(out_fd, in_fd, NULL, count, 0);
 }
 #endif
-#endif
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index a957d43..138107e 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2444,6 +2444,7 @@ extern int blkdev_fsync(struct file *filp, loff_t start, loff_t end,
 extern void block_sync_page(struct page *page);
 
 /* fs/splice.c */
+#ifdef CONFIG_SYSCALL_SPLICE
 extern ssize_t generic_file_splice_read(struct file *, loff_t *,
 		struct pipe_inode_info *, size_t, unsigned int);
 extern ssize_t default_file_splice_read(struct file *, loff_t *,
@@ -2452,6 +2453,31 @@ extern ssize_t iter_file_splice_write(struct pipe_inode_info *,
 		struct file *, loff_t *, size_t, unsigned int);
 extern ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe,
 		struct file *out, loff_t *, size_t len, unsigned int flags);
+#else
+static inline ssize_t generic_file_splice_read(struct file *in, loff_t *ppos,
+		struct pipe_inode_info *pipe, size_t len, unsigned int flags)
+{
+	return -EPERM;
+}
+
+static inline ssize_t default_file_splice_read(struct file *in, loff_t *ppos,
+		struct pipe_inode_info *pipe, size_t len, unsigned int flags)
+{
+	return -EPERM;
+}
+
+static inline ssize_t iter_file_splice_write(struct pipe_inode_info *pipe,
+		struct file *out, loff_t *ppos, size_t len, unsigned int flags)
+{
+	return -EPERM;
+}
+
+static inline ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe,
+		struct file *out, loff_t *ppos, size_t len, unsigned int flags)
+{
+	return -EPERM;
+}
+#endif
 
 extern void
 file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping);
diff --git a/include/linux/splice.h b/include/linux/splice.h
index da2751d..34570d8 100644
--- a/include/linux/splice.h
+++ b/include/linux/splice.h
@@ -65,6 +65,7 @@ typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *,
 typedef int (splice_direct_actor)(struct pipe_inode_info *,
 				  struct splice_desc *);
 
+#ifdef CONFIG_SYSCALL_SPLICE
 extern ssize_t splice_from_pipe(struct pipe_inode_info *, struct file *,
 				loff_t *, size_t, unsigned int,
 				splice_actor *);
@@ -74,13 +75,54 @@ extern ssize_t splice_to_pipe(struct pipe_inode_info *,
 			      struct splice_pipe_desc *);
 extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *,
 				      splice_direct_actor *);
+#else
+static inline ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
+			 loff_t *ppos, size_t len, unsigned int flags,
+			 splice_actor *actor)
+{
+	return -EPERM;
+}
+
+static inline ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, struct splice_desc *sd,
+			   splice_actor *actor)
+{
+	return -EPERM;
+}
+
+static inline ssize_t splice_to_pipe(struct pipe_inode_info *pipe,
+		       struct splice_pipe_desc *spd)
+{
+	return -EPERM;
+}
+
+static inline ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
+			       splice_direct_actor *actor)
+{
+	return -EPERM;
+}
+#endif
 
 /*
  * for dynamic pipe sizing
  */
+#ifdef CONFIG_SYSCALL_SPLICE
 extern int splice_grow_spd(const struct pipe_inode_info *, struct splice_pipe_desc *);
 extern void splice_shrink_spd(struct splice_pipe_desc *);
 extern void spd_release_page(struct splice_pipe_desc *, unsigned int);
+#else
+static inline int splice_grow_spd(const struct pipe_inode_info *pipe, struct splice_pipe_desc *spd)
+{
+	return -EPERM;
+}
+
+static inline void splice_shrink_spd(struct splice_pipe_desc *spd)
+{
+}
+
+static inline void spd_release_page(struct splice_pipe_desc *spd, unsigned int i)
+{
+}
+#endif
 
 extern const struct pipe_buf_operations page_cache_pipe_buf_ops;
 #endif
-- 
2.1.0

^ permalink raw reply related

* [PATCH v6 6/7] fs/nfsd: support compiling out splice
From: Pieter Smith @ 2014-12-04 17:50 UTC (permalink / raw)
  To: linux-kernel
  Cc: Josh Triplett, Pieter Smith, Alexander Duyck, Alexander Viro,
	Alexei Starovoitov, Andrew Morton, Bertrand Jacquin,
	Catalina Mocanu, Daniel Borkmann, David S. Miller, Eric Dumazet,
	Eric W. Biederman, Fabian Frederick,
	open list:FUSE: FILESYSTEM..., Geert Uytterhoeven, Hugh Dickins,
	Iulia Manda, Jan Beulich, J. Bruce Fields, Jeff Layton,
	open list:ABI/API, linux-fsd
In-Reply-To: <1417715473-24110-1-git-send-email-pieter@boesman.nl>

The goal of the larger patch set is to completely compile out fs/splice, and
as a result, splice support for all file-systems. This patch ensures that
fs/nfsd falls back to non-splice fs support when CONFIG_SYSCALL_SPLICE is
undefined.

Signed-off-by: Pieter Smith <pieter@boesman.nl>
---
 net/sunrpc/svc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index ca8a795..6cacc37 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -1084,7 +1084,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
 		goto err_short_len;
 
 	/* Will be turned off only in gss privacy case: */
-	rqstp->rq_splice_ok = true;
+	rqstp->rq_splice_ok = IS_ENABLED(CONFIG_SPLICE_SYSCALL);
 	/* Will be turned off only when NFSv4 Sessions are used */
 	rqstp->rq_usedeferral = true;
 	rqstp->rq_dropme = false;
-- 
2.1.0


^ permalink raw reply related

* [PATCH v6 5/7] net/core: support compiling out splice
From: Pieter Smith @ 2014-12-04 17:50 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: Michael S. Tsirkin, Trond Myklebust, Bertrand Jacquin,
	J. Bruce Fields, Eric Dumazet, Willem de Bruijn,
	蔡正龙, Jeff Layton, Tom Herbert,
	Alexei Starovoitov, Miklos Szeredi, Peter Foley, Hugh Dickins,
	Xiao Guangrong, Geert Uytterhoeven, Mel Gorman, Matt Turner,
	Paul E. McKenney, Alexander Duyck, Pieter Smith,
	open list:FUSE: FILESYSTEM...
In-Reply-To: <1417715473-24110-1-git-send-email-pieter-qeJ+1H9vRZbz+pZb47iToQ@public.gmane.org>

To implement splice support, net/core makes use of nosteal_pipe_buf_ops. This
struct is exported by fs/splice. The goal of the larger patch set is to
completely compile out fs/splice, so uses of the exported struct need to be
compiled out along with fs/splice.

This patch therefore compiles out splice support in net/core when
CONFIG_SYSCALL_SPLICE is undefined. The compiled out function skb_splice_bits
is transparently mocked out with a static inline. The greater patch set removes
userspace splice support so it cannot be called anyway.

Signed-off-by: Pieter Smith <pieter-qeJ+1H9vRZbz+pZb47iToQ@public.gmane.org>
---
 include/linux/skbuff.h | 10 ++++++++++
 net/core/skbuff.c      | 11 +++++++----
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index a59d934..5cd636b 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2640,9 +2640,19 @@ int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len);
 int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len);
 __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, u8 *to,
 			      int len, __wsum csum);
+#ifdef CONFIG_SYSCALL_SPLICE
 int skb_splice_bits(struct sk_buff *skb, unsigned int offset,
 		    struct pipe_inode_info *pipe, unsigned int len,
 		    unsigned int flags);
+#else
+static inline int
+skb_splice_bits(struct sk_buff *skb, unsigned int offset,
+		struct pipe_inode_info *pipe, unsigned int len,
+		unsigned int flags)
+{
+	return -EPERM;
+}
+#endif
 void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to);
 unsigned int skb_zerocopy_headlen(const struct sk_buff *from);
 int skb_zerocopy(struct sk_buff *to, struct sk_buff *from,
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 61059a0..bb426d9 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -1678,7 +1678,8 @@ EXPORT_SYMBOL(skb_copy_bits);
  * Callback from splice_to_pipe(), if we need to release some pages
  * at the end of the spd in case we error'ed out in filling the pipe.
  */
-static void sock_spd_release(struct splice_pipe_desc *spd, unsigned int i)
+static void __maybe_unused sock_spd_release(struct splice_pipe_desc *spd,
+					    unsigned int i)
 {
 	put_page(spd->pages[i]);
 }
@@ -1781,9 +1782,9 @@ static bool __splice_segment(struct page *page, unsigned int poff,
  * Map linear and fragment data from the skb to spd. It reports true if the
  * pipe is full or if we already spliced the requested length.
  */
-static bool __skb_splice_bits(struct sk_buff *skb, struct pipe_inode_info *pipe,
-			      unsigned int *offset, unsigned int *len,
-			      struct splice_pipe_desc *spd, struct sock *sk)
+static bool __maybe_unused __skb_splice_bits(struct sk_buff *skb, struct pipe_inode_info *pipe,
+					     unsigned int *offset, unsigned int *len,
+					     struct splice_pipe_desc *spd, struct sock *sk)
 {
 	int seg;
 
@@ -1821,6 +1822,7 @@ static bool __skb_splice_bits(struct sk_buff *skb, struct pipe_inode_info *pipe,
  * the frag list, if such a thing exists. We'd probably need to recurse to
  * handle that cleanly.
  */
+#ifdef CONFIG_SYSCALL_SPLICE
 int skb_splice_bits(struct sk_buff *skb, unsigned int offset,
 		    struct pipe_inode_info *pipe, unsigned int tlen,
 		    unsigned int flags)
@@ -1876,6 +1878,7 @@ done:
 
 	return ret;
 }
+#endif /* CONFIG_SYSCALL_SPLICE */
 
 /**
  *	skb_store_bits - store bits from kernel buffer to skb
-- 
2.1.0


------------------------------------------------------------------------------
Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
from Actuate! Instantly Supercharge Your Business Reports and Dashboards
with Interactivity, Sharing, Native Excel Exports, App Integration & more
Get technology previously reserved for billion-dollar corporations, FREE
http://pubads.g.doubleclick.net/gampad/clk?id=164703151&iu=/4140/ostg.clktrk

^ permalink raw reply related


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