Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH] net/ping: handle protocol mismatching scenario
From: David Miller @ 2014-11-24 21:48 UTC (permalink / raw)
  To: a17711
  Cc: linux-kernel, kuznet, jmorris, yoshfuji, kaber, netdev, stable,
	gbjc64
In-Reply-To: <1416858248-29258-1-git-send-email-a17711@motorola.com>

From: Jane Zhou <a17711@motorola.com>
Date: Mon, 24 Nov 2014 11:44:08 -0800

> ping_lookup() may return a wrong sock if sk_buff's and sock's protocols
> dont' match. For example, sk_buff's protocol is ETH_P_IPV6, but sock's
> sk_family is AF_INET, in that case, if sk->sk_bound_dev_if is zero, a wrong
> sock will be returned.
> the fix is to "continue" the searching, if no matching, return NULL.
> 
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
> Cc: James Morris <jmorris@namei.org>
> Cc: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
> Cc: Patrick McHardy <kaber@trash.net>
> Cc: netdev@vger.kernel.org
> Cc: stable@vger.kernel.org
> Signed-off-by: Jane Zhou <a17711@motorola.com>
> Signed-off-by: Yiwei Zhao <gbjc64@motorola.com>

Applied, thank you.

^ permalink raw reply

* Re: [fuse-devel] [PATCH 4/6] fs/fuse: support compiling out splice
From: Pieter Smith @ 2014-11-24 21:49 UTC (permalink / raw)
  To: Greg KH
  Cc: josh-iaAMLnmF4UmaiuxdJuQwMA, Richard Weinberger,
	Michael S. Tsirkin, Bertrand Jacquin, Oleg Nesterov,
	J. Bruce Fields, Eric Dumazet, 蔡正龙,
	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,
	open list:FUSE: FILESYSTEM...
In-Reply-To: <20141124202214.GA11362-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org>

On Mon, Nov 24, 2014 at 12:22:14PM -0800, Greg KH wrote:
> On Mon, Nov 24, 2014 at 12:14:50PM -0800, josh-iaAMLnmF4UmaiuxdJuQwMA@public.gmane.org wrote:
> > > I would, again, argue that stuff like __splice_p() not be implemented at
> > > all please.  It will only cause a huge proliferation of stuff like this
> > > that will not make any sense, and only cause a trivial, if any, amount
> > > of code savings.
> > > 
> > > I thought you were going to not do this type of thing until you got the
> > > gcc optimizer working for function callbacks.
> > 
> > Compared to the previous patchset, there are now only two instances of
> > ifdefs outside of the splice code for this, and this is one of them.  In
> > this case, the issue is no longer about making the code for this
> > splice_read function disappear, but rather to eliminate a reference to a
> > bit of splice functionality (used *inside* the FUSE splice code) that
> > will not work without SPLICE_SYSCALL.
> > 
> > Would you prefer to see this specific case handled via an #ifdef in
> > fs/fuse/dev.c rather than introducing a __splice_p that people might be
> > inclined to propagate?  That'd be fine; the code could simply wrap
> > fuse_dev_splice_read in an #ifdef and have the #else define a NULL
> > fuse_dev_splice_read.
> 
> Yes, I would prefer that, but I'm not the fuse maintainer.
> 
> thanks,
> 
> greg k-h

Okay. I'll do my part to prevent the type of proliferation guaranteed to rate
high on the respected K-H icky-scale. __splice_p() goes the way of the dodo
in favor of the solution presented by Josh.

I pray that the Gods of fuse maintenance will look favorable upon the result.

^ permalink raw reply

* Re: [PATCH] net/mlx4: Fix EEH recovery failure
From: Gavin Shan @ 2014-11-24 21:55 UTC (permalink / raw)
  To: Or Gerlitz; +Cc: Gavin Shan, Linux Netdev List, Amir Vadai, David Miller
In-Reply-To: <CAJ3xEMg_bWmDGPHUSk6HzYD7N7CBU_V6J1ovft2rEigP-DJupA@mail.gmail.com>

On Mon, Nov 24, 2014 at 11:17:55PM +0200, Or Gerlitz wrote:
>On Sat, Nov 22, 2014 at 12:56 PM, Gavin Shan <gwshan@linux.vnet.ibm.com> wrote:
>> The patch fixes couple of EEH recovery failures on PPC PowerNV
>> platform:
>
>>    * Don't clear struct mlx4_priv instance in mlx4_pci_err_detected().
>>      Otherwise, __mlx4_init_one() runs into kernel crash because
>>      of dereferencing to NULL pointer.
>
>I don't see this change in the patch, I see no-clearing of mlx4_priv
>in __mlx4_unload_one - please clarify, also is this patch
>based/targeted on the net or net-next tree?
>

Yes, It would be: Don't clear struct mlx4_priv instance in mlx4_unload_one(),
which is called by mlx4_pci_err_detected().

It's based on 3.18.rc5, where I had couple of EEH fixes on top of it.
When testing EEH with it, I hit the issue.

Thanks,
Gavin

>
>
>> With the patch applied, EEH recovery for mlx4 adapter succeeds on PPC
>> PowerNV platform.
>>
>>    # lspci
>>    0003:0f:00.0 Network controller: Mellanox Technologies \
>>    MT27500 Family [ConnectX-3]
>>
>> Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
>> ---
>>  drivers/net/ethernet/mellanox/mlx4/main.c | 3 ++-
>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
>> index 90de6e1..e118ac9 100644
>> --- a/drivers/net/ethernet/mellanox/mlx4/main.c
>> +++ b/drivers/net/ethernet/mellanox/mlx4/main.c
>> @@ -2809,7 +2809,6 @@ static void mlx4_unload_one(struct pci_dev *pdev)
>>         kfree(dev->caps.qp1_proxy);
>>         kfree(dev->dev_vfs);
>>
>> -       memset(priv, 0, sizeof(*priv));
>>         priv->pci_dev_data = pci_dev_data;
>>         priv->removed = 1;
>>  }
>> @@ -2900,6 +2899,8 @@ static pci_ers_result_t mlx4_pci_err_detected(struct pci_dev *pdev,
>>                                               pci_channel_state_t state)
>>  {
>>         mlx4_unload_one(pdev);
>> +       pci_release_regions(pdev);
>> +       pci_disable_device(pdev);
>>
>>         return state == pci_channel_io_perm_failure ?
>>                 PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET;
>> --
>> 1.8.3.2
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe netdev" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply

* Re: [PATCH] net-timestamp: Fix a documentation typo
From: Willem de Bruijn @ 2014-11-24 22:11 UTC (permalink / raw)
  To: Andy Lutomirski; +Cc: Network Development, David S. Miller
In-Reply-To: <ca6ac789334c26905d86f2a596878d2dc18e69e9.1416859110.git.luto@amacapital.net>

On Mon, Nov 24, 2014 at 3:02 PM, Andy Lutomirski <luto@amacapital.net> wrote:
> SOF_TIMESTAMPING_OPT_ID puts the id in ee_data, not ee_info.
>
> Cc: Willem de Bruijn <willemb@google.com>
> Signed-off-by: Andy Lutomirski <luto@amacapital.net>

Acked-by: Willem de Bruijn <willemb@google.com>

> ---

Thanks for sending a fix.

> While I'm here, the docs say:
>
>     In practice, it [ee_data] is a monotonically increasing u32 (that wraps).
>
> Is user code supposed to rely on this and, further, on the fact that the
> counter starts at zero?  If not, how else is user code supposed to match
> outgoing data to timestamps?

That is correct. The per-socket counter is reset when
SOF_TIMESTAMPING_OPT_ID is set. On datagram sockets, it returns the
packet number since the reset. On stream sockets, it returns the byte
offset since the reset.

> Also, is it intentional that the payload data associated with the tx
> timestamp is (I think) the full outgoing packet including lower-layer
> headers?

Absolutely not. I'll look into that right away. It doesn't on ACK, and
should certainly not expose this info in the other cases, either.

> And, finally, would it be possible to attach IP_PKTINFO to the looped
> timestamp?  That way I could finally update my fancy ping program to
> track which outgoing interface was used for a request.

If socket option IP_PKTINFO is set, you want to receive in_pktinfo for
any packet that happens to be queued onto the error queue? Both
SKB_EXT_ERR(skb) and PKTINFO_SKB_CB(skb) use the control block to
store data that is later encoded in a cmsg, so there may not be enough
room to hold both. I'll take a look.

^ permalink raw reply

* Re: [PATCH] net-timestamp: Fix a documentation typo
From: Andy Lutomirski @ 2014-11-24 22:18 UTC (permalink / raw)
  To: Willem de Bruijn; +Cc: Network Development, David S. Miller
In-Reply-To: <CA+FuTSenSVXP-=hH+erpoE7yz1HbF8n9PeD_Xof-W=3GaQ6OFA@mail.gmail.com>

On Mon, Nov 24, 2014 at 2:11 PM, Willem de Bruijn <willemb@google.com> wrote:
> On Mon, Nov 24, 2014 at 3:02 PM, Andy Lutomirski <luto@amacapital.net> wrote:
>> SOF_TIMESTAMPING_OPT_ID puts the id in ee_data, not ee_info.
>>
>> Cc: Willem de Bruijn <willemb@google.com>
>> Signed-off-by: Andy Lutomirski <luto@amacapital.net>
>
> Acked-by: Willem de Bruijn <willemb@google.com>
>
>> ---
>
> Thanks for sending a fix.
>
>> While I'm here, the docs say:
>>
>>     In practice, it [ee_data] is a monotonically increasing u32 (that wraps).
>>
>> Is user code supposed to rely on this and, further, on the fact that the
>> counter starts at zero?  If not, how else is user code supposed to match
>> outgoing data to timestamps?
>
> That is correct. The per-socket counter is reset when
> SOF_TIMESTAMPING_OPT_ID is set. On datagram sockets, it returns the
> packet number since the reset. On stream sockets, it returns the byte
> offset since the reset.
>

It might be worth tweaking the docs at some point to make this clearer.

>> Also, is it intentional that the payload data associated with the tx
>> timestamp is (I think) the full outgoing packet including lower-layer
>> headers?
>
> Absolutely not. I'll look into that right away. It doesn't on ACK, and
> should certainly not expose this info in the other cases, either.

Then I won't start trying to decode it :)

TBH, all I looked at was the packet size, which matched the full
link-layer packet.

Also, the address returned by recvmsg appeared to be garbage instead
of 0.0.0.0 (or something meaningful, whatever that would be).

>
>> And, finally, would it be possible to attach IP_PKTINFO to the looped
>> timestamp?  That way I could finally update my fancy ping program to
>> track which outgoing interface was used for a request.
>
> If socket option IP_PKTINFO is set, you want to receive in_pktinfo for
> any packet that happens to be queued onto the error queue? Both
> SKB_EXT_ERR(skb) and PKTINFO_SKB_CB(skb) use the control block to
> store data that is later encoded in a cmsg, so there may not be enough
> room to hold both. I'll take a look.

I don't really care what the mechanism is, but it would be really nice
if I could see what interface the send timestamp is associated with.

Also, thanks for this new feature.  It's great!

--Andy

^ permalink raw reply

* Re: [PATCH] net-timestamp: Fix a documentation typo
From: Willem de Bruijn @ 2014-11-24 22:38 UTC (permalink / raw)
  To: Andy Lutomirski; +Cc: Network Development, David S. Miller
In-Reply-To: <CALCETrU6tjwZoSCdfXnnhRy5H0uG9B8h5ftu9tA42iBuLXTQog@mail.gmail.com>

>>> Is user code supposed to rely on this and, further, on the fact that the
>>> counter starts at zero?  If not, how else is user code supposed to match
>>> outgoing data to timestamps?
>>
>> That is correct. The per-socket counter is reset when
>> SOF_TIMESTAMPING_OPT_ID is set. On datagram sockets, it returns the
>> packet number since the reset. On stream sockets, it returns the byte
>> offset since the reset.
>>
>
> It might be worth tweaking the docs at some point to make this clearer.

Good point. The commit message is apparently more informative than the
actual documentation.

>>> Also, is it intentional that the payload data associated with the tx
>>> timestamp is (I think) the full outgoing packet including lower-layer
>>> headers?
>>
>> Absolutely not. I'll look into that right away. It doesn't on ACK, and
>> should certainly not expose this info in the other cases, either.
>
> Then I won't start trying to decode it :)

The datagram feature existed before I added the counter and stream
support, so returning the entire packet in that case is legacy
behavior, I suppose. I did not intend to expose network headers for
the new stream socket interface, though.

> TBH, all I looked at was the packet size, which matched the full
> link-layer packet.
>
> Also, the address returned by recvmsg appeared to be garbage instead
> of 0.0.0.0 (or something meaningful, whatever that would be).
>
>>
>>> And, finally, would it be possible to attach IP_PKTINFO to the looped
>>> timestamp?  That way I could finally update my fancy ping program to
>>> track which outgoing interface was used for a request.
>>
>> If socket option IP_PKTINFO is set, you want to receive in_pktinfo for
>> any packet that happens to be queued onto the error queue? Both
>> SKB_EXT_ERR(skb) and PKTINFO_SKB_CB(skb) use the control block to
>> store data that is later encoded in a cmsg, so there may not be enough
>> room to hold both. I'll take a look.
>
> I don't really care what the mechanism is, but it would be really nice
> if I could see what interface the send timestamp is associated with.

Okay. I'll see if I can cook something up.

> Also, thanks for this new feature.  It's great!

Thanks!

> --Andy

^ permalink raw reply

* Re: [RFC PATCH 0/4] switch device: offload policy attributes
From: Roopa Prabhu @ 2014-11-24 23:00 UTC (permalink / raw)
  To: Scott Feldman
  Cc: Jiří Pírko, Jamal Hadi Salim, Benjamin LaHaise,
	Thomas Graf, john.fastabend, stephen, John Linville, nhorman,
	Nicolas Dichtel, vyasevic, Florian Fainelli, buytenh, Aviad Raveh,
	Netdev, David S. Miller, Shrijeet Mukherjee, Andy Gospodarek
In-Reply-To: <CAE4R7bAY2zMy4SiuwhdXyH2Swqv1KfkrBJ_ZwU_RYdCW3k+Mvg@mail.gmail.com>

On 11/24/14, 12:48 PM, Scott Feldman wrote:
> On Mon, Nov 24, 2014 at 4:55 AM, Roopa Prabhu <roopa@cumulusnetworks.com> wrote:
>> On 11/24/14, 2:18 AM, Scott Feldman wrote:
>>> Hi Roopa,
>>>
>>> I have a patch pending against Jiri's v2 that's uses existing
>>> ndo_bridge_setlink/getlink to push policy settings down to port driver
>>> for controlling HW offload.  I had to make a few tweaks, but for the
>>> most part setlink/getlink already has the master/self semantics so
>>> users can set policy flags on bridge's SW version of the port (master)
>>> or on the offloaded version of the port (self).
>>>     I added the new
>>> hwmode option "swdev" to the existing "vepa"|"veb" choices.  When you
>>> specify hwmode, SELF is set and the port driver's setlink get's
>>> called.  Did you look at setlink/getlink?  It looks like the kernel
>>> and iproute2 where going down this route of using setlink/getlink for
>>> SELF policy, so I'm wondering if we need more?
>> If i understand you correctly, this will mean the port driver implements the
>> setlink/getlink with the  bridge port flags and attributes. And, it also
>> means
>> the port driver will parse the netlink msg instead of the bridge driver
>> parsing all attributes and then calling offloads.
> Yes, exactly, the port driver parses/fills bridge_setlink/getlink
> netlink msg to set/get port settings.  It's basically a passthru for
> rtnl_bridge_setlink/getlink handling RTM_GETLNK/RTM_SETLINK on
> PF_BRIDGE.
This will duplicate msg parsing code and validation code in the kernel 
bridge driver and in all the port drivers.
If this is the path we plan to go down on,...it will also mean we will 
do the same thing
for bonds, vxlans and maybe others in the future.

In the mode where kernel and hw state need to remain in sync,
I am also concerned about how we handle failure cases.

I think we will have cases where the kernel will set the attribute and 
hw will fail. In which case can we rollback ?

>> But, in cases where we want bridge port flags and attributes set both in hw
>> and sw,
>> the user (iproute2) will have to set both MASTER and SELF flags, and the
>> netlink parsing will now happen in two places, the bridge driver and the
>> bridge port
>> driver ?
> Yes, that's correct.  That seems to be the intent of the current
> design based on the existing code.  I had to do minor changes to get
> brport flags passed back up in getlink, but for the most part the
> kernel code and iproute2 code where already setup to support this dual
> master/self model.  As an example, let's consider the flags
> IFLA_BRPORT_LEARNING.  User can set learning on/off on bridge's port
> (master) and can independently set learning on/off on port driver
> (self) in HW.  So for typical swdev setups, the port driver would
> default to learning ON and the bridge would default to learning ON.
> The user would probably want to turn learning OFF on the bridge, but
> all combinations of ON/OFF are available.  A better example is
> IFLA_BRPORT_FLOOD.  If we had a single flag that applied to both
> master and self, we'd run into trouble in the flooding ON case.  We
> don't want both the HW and bridge driver flooding as this would result
> in duplicate egress pkts.  If we turn flooding OFF, then neither HW or
> SW flood and our bridge is broken.  So we want SW bridge (master)
> flooding OFF and port driver (self) have flooding ON, for the
> optimized HW-offload case.
>
>> For bridge stp state updates, the bridge driver will call the ports->setlink
>> ndo op ?
> No, we added a new ndo op to communicate STP state changes to port
> driver.  STP state transitions don't really fit into the
> setlink/getlink model, although you reminded me there was a request
> for a policy flag to turn STP pushes down to port driver ON/OFF.
>
>> (We should probably rename the ndo_bridge_setlink to ndo_setlink)
> The name seems correct as they're specific to RTM_GETLNK/SETLNK for PF_BRIDGE.

But, SETLINK/GETLINK Is general across all link objects. It can be bonds 
and vxlan interfaces too.

>
>>> On FDB entries, using master/self semantics that exist, it's clear
>>> which are owned by offloaded device and which are owned by bridge.
>>> The one missing annotation was a flag indicating FDB entry in bridge
>>> was synced from device.  And a policy flag to turn on/off syncing from
>>> the device.  The policy flag is just another IFLA_BRPORT flags passed
>>> with setlink/getlink.
>>>
>>> The setlink/getlink patch will go out in v3 once I finish testing it
>>> and push it to Jiri.  Hopefully tomorrow.
>>
>> In my patches, I used newlink..., but in most cases all attributes set via
>> newlink can be
>> used with setlink and hence getlink. So, i think we are close here.
>>
>> But, Oh wait, i am talking about rtnl_link_ops
>> ->newlink/changelink/getlink/dellink. I did not
>> realize there was a parallel ndo op to this. But thats probably because,
>> rtnl_link_ops can be
>> used only for logical devices. But, i see bridge driver implementing both
>> the
>> rtnl_link_ops changelink and ndo op setlink. hmm..seems like a lot of
>> duplication.
>> Will look closely some more.
>>
>>
>> Coming back to my series, i was trying to get a common set of flags for all
>> netdevs
>> (bridge, bond, vxlans so far), and hence the common flag in 'struct
>> ifiinfomsg'.
>>
>> But, I am all for using existing infrastructure if it fits well.
> Jiri updated his net-next-rocker tree with my latest but hasn't pushed
> out v3 yet.  You can see for bridging at least we now have the policy
> flag support for master/self without much heavy lifting in kernel or
> iproute2 code.  It seems like the right move at this time, with low
> chance of regressions or breaking backward compat.
>
>> For the fdb offloads, the NTF_SELF and NTF_MASTER is in 'struct
>> ndmsg->ndm_flags', which is also
>> what i was proposing. So, ack there.
> Ya, for FDB, the master/self model works slick and support is already
> there so we should use it.
>
>> For the bridge netdev, using the flag in IFLA_BRIDGE_FLAGS, is also ok.
> Agreed.
>
>> I will look at your patches when they are out.
> v3 is imminent.  You can pull net-next-rocker now to look it over.
>
>
ok, thanks.

^ permalink raw reply

* [PATCH v4 0/7] kernel tinification: optionally compile out splice family of syscalls (splice, vmsplice, tee and sendfile)
From: Pieter Smith @ 2014-11-24 23:00 UTC (permalink / raw)
  To: pieter
  Cc: Josh Triplett, 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-fsdevel, linux-kernel

REPO: https://github.com/smipi1/linux-tinification.git

BRANCH: tiny/config-syscall-splice

BACKGROUND: This patch-set forms part of the Linux Kernel Tinification effort (
  https://tiny.wiki.kernel.org/).

GOAL: Support compiling out the splice family of syscalls (splice, vmsplice,
  tee and sendfile) along with all supporting infrastructure if not needed.
  Many embedded systems will not need the splice-family syscalls. Omitting them
  saves space.

HISTORY:
  PATCH v4:
    - Drops __splice_p()
    - Let nfsd fall back to non-splice support when splice is compiled out
    - Style fixes
  
  PATCH v3:
    - Fixup commit logs so that they are consistent with patch strategy
    - Style fixes
  
  PATCH v2:
    - Avoid the ifdef mess introduced in PATCH v1 by mocking out exported splice
      functions.

STRATEGY:
a. With the goal of eventually compiling out fs/splice.c, several functions
   that are only used in support of the the splice family of syscalls are moved
   into fs/splice.c from fs/read_write.c. The kernel_write function that is not
   used to support the splice syscalls is moved to fs/read_write.c.

b. Introduce an EXPERT kernel configuration option; CONFIG_SYSCALL_SPLICE; to
   compile out the splice family of syscalls. This removes all userspace uses
   of the splice infrastructure.

c. Splice exports an operations struct, nosteal_pipe_buf_ops. Eliminate the 
   use of this struct when CONFIG_SYSCALL_SPLICE is undefined, so that splice
   can later be compiled out.

d. Let nfsd fall back to non-splice support when splice is compiled out.

e. Compile out fs/splice.c. Functions exported by fs/splice are mocked out with
   failing static inlines. This is done so as to all but eliminate the
   maintenance burden on file-system drivers.

RESULTS: A tinyconfig bloat-o-meter score for the entire patch-set:

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

Pieter Smith (7):
  fs: move sendfile syscall into fs/splice
  fs: moved kernel_write to fs/read_write
  fs/splice: support compiling out splice-family syscalls
  fs/fuse: support compiling out splice
  fs/nfsd: support compiling out splice
  net/core: support compiling out splice
  fs/splice: full support for compiling out splice

 fs/Makefile            |   3 +-
 fs/fuse/dev.c          |   9 ++-
 fs/read_write.c        | 181 +++------------------------------------------
 fs/splice.c            | 194 +++++++++++++++++++++++++++++++++++++++++++++----
 include/linux/fs.h     |  26 +++++++
 include/linux/skbuff.h |  10 +++
 include/linux/splice.h |  42 +++++++++++
 init/Kconfig           |  10 +++
 kernel/sys_ni.c        |   8 ++
 net/core/skbuff.c      |  11 ++-
 net/sunrpc/svc.c       |   2 +-
 11 files changed, 302 insertions(+), 194 deletions(-)

-- 
2.1.0

^ permalink raw reply

* [PATCH v4 1/7] fs: move sendfile syscall into fs/splice
From: Pieter Smith @ 2014-11-24 23:01 UTC (permalink / raw)
  To: pieter
  Cc: Josh Triplett, 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-fsdevel, linux-kernel
In-Reply-To: <1416870079-15254-1-git-send-email-pieter@boesman.nl>

sendfile functionally forms part of the splice group of syscalls (splice,
vmsplice and tee). Grouping sendfile with splice paves the way to compiling out
the splice group of syscalls for embedded systems that do not need these.

add/remove: 0/0 grow/shrink: 7/2 up/down: 86/-61 (25)
function                                     old     new   delta
file_start_write                              34      68     +34
file_end_write                                29      58     +29
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
sys_tee                                      497     491      -6
sys_splice                                  1075    1020     -55

Signed-off-by: Pieter Smith <pieter@boesman.nl>
---
 fs/read_write.c | 175 -------------------------------------------------------
 fs/splice.c     | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 178 insertions(+), 175 deletions(-)

diff --git a/fs/read_write.c b/fs/read_write.c
index 7d9318c..d9451ba 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -1191,178 +1191,3 @@ COMPAT_SYSCALL_DEFINE5(pwritev, compat_ulong_t, fd,
 }
 #endif
 
-static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
-		  	   size_t count, loff_t max)
-{
-	struct fd in, out;
-	struct inode *in_inode, *out_inode;
-	loff_t pos;
-	loff_t out_pos;
-	ssize_t retval;
-	int fl;
-
-	/*
-	 * Get input file, and verify that it is ok..
-	 */
-	retval = -EBADF;
-	in = fdget(in_fd);
-	if (!in.file)
-		goto out;
-	if (!(in.file->f_mode & FMODE_READ))
-		goto fput_in;
-	retval = -ESPIPE;
-	if (!ppos) {
-		pos = in.file->f_pos;
-	} else {
-		pos = *ppos;
-		if (!(in.file->f_mode & FMODE_PREAD))
-			goto fput_in;
-	}
-	retval = rw_verify_area(READ, in.file, &pos, count);
-	if (retval < 0)
-		goto fput_in;
-	count = retval;
-
-	/*
-	 * Get output file, and verify that it is ok..
-	 */
-	retval = -EBADF;
-	out = fdget(out_fd);
-	if (!out.file)
-		goto fput_in;
-	if (!(out.file->f_mode & FMODE_WRITE))
-		goto fput_out;
-	retval = -EINVAL;
-	in_inode = file_inode(in.file);
-	out_inode = file_inode(out.file);
-	out_pos = out.file->f_pos;
-	retval = rw_verify_area(WRITE, out.file, &out_pos, count);
-	if (retval < 0)
-		goto fput_out;
-	count = retval;
-
-	if (!max)
-		max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);
-
-	if (unlikely(pos + count > max)) {
-		retval = -EOVERFLOW;
-		if (pos >= max)
-			goto fput_out;
-		count = max - pos;
-	}
-
-	fl = 0;
-#if 0
-	/*
-	 * We need to debate whether we can enable this or not. The
-	 * man page documents EAGAIN return for the output at least,
-	 * and the application is arguably buggy if it doesn't expect
-	 * EAGAIN on a non-blocking file descriptor.
-	 */
-	if (in.file->f_flags & O_NONBLOCK)
-		fl = SPLICE_F_NONBLOCK;
-#endif
-	file_start_write(out.file);
-	retval = do_splice_direct(in.file, &pos, out.file, &out_pos, count, fl);
-	file_end_write(out.file);
-
-	if (retval > 0) {
-		add_rchar(current, retval);
-		add_wchar(current, retval);
-		fsnotify_access(in.file);
-		fsnotify_modify(out.file);
-		out.file->f_pos = out_pos;
-		if (ppos)
-			*ppos = pos;
-		else
-			in.file->f_pos = pos;
-	}
-
-	inc_syscr(current);
-	inc_syscw(current);
-	if (pos > max)
-		retval = -EOVERFLOW;
-
-fput_out:
-	fdput(out);
-fput_in:
-	fdput(in);
-out:
-	return retval;
-}
-
-SYSCALL_DEFINE4(sendfile, int, out_fd, int, in_fd, off_t __user *, offset, size_t, count)
-{
-	loff_t pos;
-	off_t off;
-	ssize_t ret;
-
-	if (offset) {
-		if (unlikely(get_user(off, offset)))
-			return -EFAULT;
-		pos = off;
-		ret = do_sendfile(out_fd, in_fd, &pos, count, MAX_NON_LFS);
-		if (unlikely(put_user(pos, offset)))
-			return -EFAULT;
-		return ret;
-	}
-
-	return do_sendfile(out_fd, in_fd, NULL, count, 0);
-}
-
-SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd, loff_t __user *, offset, size_t, count)
-{
-	loff_t pos;
-	ssize_t ret;
-
-	if (offset) {
-		if (unlikely(copy_from_user(&pos, offset, sizeof(loff_t))))
-			return -EFAULT;
-		ret = do_sendfile(out_fd, in_fd, &pos, count, 0);
-		if (unlikely(put_user(pos, offset)))
-			return -EFAULT;
-		return ret;
-	}
-
-	return do_sendfile(out_fd, in_fd, NULL, count, 0);
-}
-
-#ifdef CONFIG_COMPAT
-COMPAT_SYSCALL_DEFINE4(sendfile, int, out_fd, int, in_fd,
-		compat_off_t __user *, offset, compat_size_t, count)
-{
-	loff_t pos;
-	off_t off;
-	ssize_t ret;
-
-	if (offset) {
-		if (unlikely(get_user(off, offset)))
-			return -EFAULT;
-		pos = off;
-		ret = do_sendfile(out_fd, in_fd, &pos, count, MAX_NON_LFS);
-		if (unlikely(put_user(pos, offset)))
-			return -EFAULT;
-		return ret;
-	}
-
-	return do_sendfile(out_fd, in_fd, NULL, count, 0);
-}
-
-COMPAT_SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd,
-		compat_loff_t __user *, offset, compat_size_t, count)
-{
-	loff_t pos;
-	ssize_t ret;
-
-	if (offset) {
-		if (unlikely(copy_from_user(&pos, offset, sizeof(loff_t))))
-			return -EFAULT;
-		ret = do_sendfile(out_fd, in_fd, &pos, count, 0);
-		if (unlikely(put_user(pos, offset)))
-			return -EFAULT;
-		return ret;
-	}
-
-	return do_sendfile(out_fd, in_fd, NULL, count, 0);
-}
-#endif
diff --git a/fs/splice.c b/fs/splice.c
index f5cb9ba..c1a2861 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -28,6 +28,7 @@
 #include <linux/export.h>
 #include <linux/syscalls.h>
 #include <linux/uio.h>
+#include <linux/fsnotify.h>
 #include <linux/security.h>
 #include <linux/gfp.h>
 #include <linux/socket.h>
@@ -2039,3 +2040,180 @@ SYSCALL_DEFINE4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags)
 
 	return error;
 }
+
+static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
+			   size_t count, loff_t max)
+{
+	struct fd in, out;
+	struct inode *in_inode, *out_inode;
+	loff_t pos;
+	loff_t out_pos;
+	ssize_t retval;
+	int fl;
+
+	/*
+	 * Get input file, and verify that it is ok..
+	 */
+	retval = -EBADF;
+	in = fdget(in_fd);
+	if (!in.file)
+		goto out;
+	if (!(in.file->f_mode & FMODE_READ))
+		goto fput_in;
+	retval = -ESPIPE;
+	if (!ppos) {
+		pos = in.file->f_pos;
+	} else {
+		pos = *ppos;
+		if (!(in.file->f_mode & FMODE_PREAD))
+			goto fput_in;
+	}
+	retval = rw_verify_area(READ, in.file, &pos, count);
+	if (retval < 0)
+		goto fput_in;
+	count = retval;
+
+	/*
+	 * Get output file, and verify that it is ok..
+	 */
+	retval = -EBADF;
+	out = fdget(out_fd);
+	if (!out.file)
+		goto fput_in;
+	if (!(out.file->f_mode & FMODE_WRITE))
+		goto fput_out;
+	retval = -EINVAL;
+	in_inode = file_inode(in.file);
+	out_inode = file_inode(out.file);
+	out_pos = out.file->f_pos;
+	retval = rw_verify_area(WRITE, out.file, &out_pos, count);
+	if (retval < 0)
+		goto fput_out;
+	count = retval;
+
+	if (!max)
+		max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);
+
+	if (unlikely(pos + count > max)) {
+		retval = -EOVERFLOW;
+		if (pos >= max)
+			goto fput_out;
+		count = max - pos;
+	}
+
+	fl = 0;
+#if 0
+	/*
+	 * We need to debate whether we can enable this or not. The
+	 * man page documents EAGAIN return for the output at least,
+	 * and the application is arguably buggy if it doesn't expect
+	 * EAGAIN on a non-blocking file descriptor.
+	 */
+	if (in.file->f_flags & O_NONBLOCK)
+		fl = SPLICE_F_NONBLOCK;
+#endif
+	file_start_write(out.file);
+	retval = do_splice_direct(in.file, &pos, out.file, &out_pos, count, fl);
+	file_end_write(out.file);
+
+	if (retval > 0) {
+		add_rchar(current, retval);
+		add_wchar(current, retval);
+		fsnotify_access(in.file);
+		fsnotify_modify(out.file);
+		out.file->f_pos = out_pos;
+		if (ppos)
+			*ppos = pos;
+		else
+			in.file->f_pos = pos;
+	}
+
+	inc_syscr(current);
+	inc_syscw(current);
+	if (pos > max)
+		retval = -EOVERFLOW;
+
+fput_out:
+	fdput(out);
+fput_in:
+	fdput(in);
+out:
+	return retval;
+}
+
+SYSCALL_DEFINE4(sendfile, int, out_fd, int, in_fd, off_t __user *, offset, size_t, count)
+{
+	loff_t pos;
+	off_t off;
+	ssize_t ret;
+
+	if (offset) {
+		if (unlikely(get_user(off, offset)))
+			return -EFAULT;
+		pos = off;
+		ret = do_sendfile(out_fd, in_fd, &pos, count, MAX_NON_LFS);
+		if (unlikely(put_user(pos, offset)))
+			return -EFAULT;
+		return ret;
+	}
+
+	return do_sendfile(out_fd, in_fd, NULL, count, 0);
+}
+
+SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd, loff_t __user *, offset, size_t, count)
+{
+	loff_t pos;
+	ssize_t ret;
+
+	if (offset) {
+		if (unlikely(copy_from_user(&pos, offset, sizeof(loff_t))))
+			return -EFAULT;
+		ret = do_sendfile(out_fd, in_fd, &pos, count, 0);
+		if (unlikely(put_user(pos, offset)))
+			return -EFAULT;
+		return ret;
+	}
+
+	return do_sendfile(out_fd, in_fd, NULL, count, 0);
+}
+
+#ifdef CONFIG_COMPAT
+COMPAT_SYSCALL_DEFINE4(sendfile, int, out_fd, int, in_fd,
+		compat_off_t __user *, offset, compat_size_t, count)
+{
+	loff_t pos;
+	off_t off;
+	ssize_t ret;
+
+	if (offset) {
+		if (unlikely(get_user(off, offset)))
+			return -EFAULT;
+		pos = off;
+		ret = do_sendfile(out_fd, in_fd, &pos, count, MAX_NON_LFS);
+		if (unlikely(put_user(pos, offset)))
+			return -EFAULT;
+		return ret;
+	}
+
+	return do_sendfile(out_fd, in_fd, NULL, count, 0);
+}
+
+COMPAT_SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd,
+		compat_loff_t __user *, offset, compat_size_t, count)
+{
+	loff_t pos;
+	ssize_t ret;
+
+	if (offset) {
+		if (unlikely(copy_from_user(&pos, offset, sizeof(loff_t))))
+			return -EFAULT;
+		ret = do_sendfile(out_fd, in_fd, &pos, count, 0);
+		if (unlikely(put_user(pos, offset)))
+			return -EFAULT;
+		return ret;
+	}
+
+	return do_sendfile(out_fd, in_fd, NULL, count, 0);
+}
+#endif
+
-- 
2.1.0

^ permalink raw reply related

* [PATCH v4 2/7] fs: moved kernel_write to fs/read_write
From: Pieter Smith @ 2014-11-24 23:01 UTC (permalink / raw)
  To: pieter
  Cc: Josh Triplett, 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-fsdevel, linux-kernel
In-Reply-To: <1416870079-15254-1-git-send-email-pieter@boesman.nl>

kernel_write shares infrastructure with the read_write translation unit but not
with the splice translation unit. Grouping kernel_write with the read_write
translation unit is more logical. It also paves the way to compiling out the
splice group of syscalls for embedded systems that do not need them.

Signed-off-by: Pieter Smith <pieter@boesman.nl>
---
 fs/read_write.c | 16 ++++++++++++++++
 fs/splice.c     | 16 ----------------
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/fs/read_write.c b/fs/read_write.c
index d9451ba..f4c8d8b 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -1191,3 +1191,19 @@ COMPAT_SYSCALL_DEFINE5(pwritev, compat_ulong_t, fd,
 }
 #endif
 
+ssize_t kernel_write(struct file *file, const char *buf, size_t count,
+			    loff_t pos)
+{
+	mm_segment_t old_fs;
+	ssize_t res;
+
+	old_fs = get_fs();
+	set_fs(get_ds());
+	/* The cast to a user pointer is valid due to the set_fs() */
+	res = vfs_write(file, (__force const char __user *)buf, count, &pos);
+	set_fs(old_fs);
+
+	return res;
+}
+EXPORT_SYMBOL(kernel_write);
+
diff --git a/fs/splice.c b/fs/splice.c
index c1a2861..44b201b 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -583,22 +583,6 @@ static ssize_t kernel_readv(struct file *file, const struct iovec *vec,
 	return res;
 }
 
-ssize_t kernel_write(struct file *file, const char *buf, size_t count,
-			    loff_t pos)
-{
-	mm_segment_t old_fs;
-	ssize_t res;
-
-	old_fs = get_fs();
-	set_fs(get_ds());
-	/* The cast to a user pointer is valid due to the set_fs() */
-	res = vfs_write(file, (__force const char __user *)buf, count, &pos);
-	set_fs(old_fs);
-
-	return res;
-}
-EXPORT_SYMBOL(kernel_write);
-
 ssize_t default_file_splice_read(struct file *in, loff_t *ppos,
 				 struct pipe_inode_info *pipe, size_t len,
 				 unsigned int flags)
-- 
2.1.0

^ permalink raw reply related

* [PATCH v4 4/7] fs/fuse: support compiling out splice
From: Pieter Smith @ 2014-11-24 23:01 UTC (permalink / raw)
  To: pieter
  Cc: Josh Triplett, 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-fsdevel, linux-kernel
In-Reply-To: <1416870079-15254-1-git-send-email-pieter@boesman.nl>

To implement splice support, fs/fuse 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 fs/fuse when
CONFIG_SYSCALL_SPLICE is undefined.

Signed-off-by: Pieter Smith <pieter@boesman.nl>
---
 fs/fuse/dev.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index ca88731..e984302 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -1191,8 +1191,9 @@ __releases(fc->lock)
  * request_end().  Otherwise add it to the processing list, and set
  * the 'sent' flag.
  */
-static ssize_t fuse_dev_do_read(struct fuse_conn *fc, struct file *file,
-				struct fuse_copy_state *cs, size_t nbytes)
+static ssize_t __maybe_unused
+fuse_dev_do_read(struct fuse_conn *fc, struct file *file,
+		 struct fuse_copy_state *cs, size_t nbytes)
 {
 	int err;
 	struct fuse_req *req;
@@ -1291,6 +1292,7 @@ static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov,
 	return fuse_dev_do_read(fc, file, &cs, iov_length(iov, nr_segs));
 }
 
+#ifdef CONFIG_SYSCALL_SPLICE
 static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,
 				    struct pipe_inode_info *pipe,
 				    size_t len, unsigned int flags)
@@ -1368,6 +1370,9 @@ out:
 	kfree(bufs);
 	return ret;
 }
+#else /* CONFIG_SYSCALL_SPLICE */
+#define fuse_dev_splice_read NULL
+#endif
 
 static int fuse_notify_poll(struct fuse_conn *fc, unsigned int size,
 			    struct fuse_copy_state *cs)
-- 
2.1.0

^ permalink raw reply related

* [PATCH v4 5/7] fs/nfsd: support compiling out splice
From: Pieter Smith @ 2014-11-24 23:01 UTC (permalink / raw)
  To: pieter
  Cc: Josh Triplett, 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-fsdevel, linux-kernel
In-Reply-To: <1416870079-15254-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 v4 6/7] net/core: support compiling out splice
From: Pieter Smith @ 2014-11-24 23:01 UTC (permalink / raw)
  To: pieter-qeJ+1H9vRZbz+pZb47iToQ
  Cc: Michael S. Tsirkin, Trond Myklebust, Bertrand Jacquin,
	Oleg Nesterov, 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, open list:FUSE: FILESYSTEM...
In-Reply-To: <1416870079-15254-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=157005751&iu=/4140/ostg.clktrk

^ permalink raw reply related

* [PATCH v4 7/7] fs/splice: full support for compiling out splice
From: Pieter Smith @ 2014-11-24 23:01 UTC (permalink / raw)
  To: pieter
  Cc: Josh Triplett, 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-fsdevel, linux-kernel
In-Reply-To: <1416870079-15254-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 v4 3/7] fs/splice: support compiling out splice-family syscalls
From: Pieter Smith @ 2014-11-24 23:01 UTC (permalink / raw)
  To: pieter
  Cc: Josh Triplett, 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-fsdevel, linux-kernel
In-Reply-To: <1416870079-15254-1-git-send-email-pieter@boesman.nl>

Many embedded systems will not need the splice-family syscalls (splice,
vmsplice, tee and sendfile). Omitting them saves space.  This adds a new EXPERT
config option CONFIG_SYSCALL_SPLICE (default y) to support compiling them out.

The goal is to completely compile out fs/splice along with the syscalls. To
achieve this, the remaining patch-set will deal with fs/splice exports. As far
as possible, the impact on other device drivers will be minimized so as to
reduce the overal maintenance burden of CONFIG_SYSCALL_SPLICE.

The use of exported functions will be solved by transparently mocking them out
with static inlines. Uses of the exported pipe_buf_operations struct however
require direct modification in fs/fuse and net/core. The next two patches will
deal with this. A macro is defined that will assist with NULL'ing out callbacks
when CONFIG_SYSCALL_SPLICE is undefined: __splice_p().

Once all exports are solved, fs/splice can be compiled out.

The bloat benefit of this patch given a tinyconfig is:

add/remove: 0/16 grow/shrink: 2/5 up/down: 114/-3693 (-3579)
function                                     old     new   delta
splice_direct_to_actor                       348     416     +68
splice_to_pipe                               371     417     +46
splice_from_pipe_next                        107     106      -1
fdput                                         11       -     -11
signal_pending                                39      26     -13
fdget                                         56      42     -14
user_page_pipe_buf_ops                        20       -     -20
user_page_pipe_buf_steal                      25       -     -25
file_end_write                                58      29     -29
file_start_write                              68      34     -34
pipe_to_user                                  43       -     -43
wakeup_pipe_readers                           54       -     -54
do_splice_to                                  87       -     -87
ipipe_prep.part                               92       -     -92
opipe_prep.part                              119       -    -119
sys_sendfile                                 122       -    -122
sys_sendfile64                               126       -    -126
sys_vmsplice                                 137       -    -137
vmsplice_to_user                             205       -    -205
sys_tee                                      491       -    -491
do_sendfile                                  492       -    -492
vmsplice_to_pipe                             558       -    -558
sys_splice                                  1020       -   -1020

Signed-off-by: Pieter Smith <pieter@boesman.nl>
---
 fs/splice.c     |  2 ++
 init/Kconfig    | 10 ++++++++++
 kernel/sys_ni.c |  8 ++++++++
 3 files changed, 20 insertions(+)

diff --git a/fs/splice.c b/fs/splice.c
index 44b201b..7c4c695 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -1316,6 +1316,7 @@ 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);
@@ -2200,4 +2201,5 @@ 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/init/Kconfig b/init/Kconfig
index d811d5f..dec9819 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1571,6 +1571,16 @@ config NTP
 	  system clock to an NTP server, you can disable this option to save
 	  space.
 
+config SYSCALL_SPLICE
+	bool "Enable splice/vmsplice/tee/sendfile syscalls" if EXPERT
+	default y
+	help
+	  This option enables the splice, vmsplice, tee and sendfile syscalls. These
+	  are used by applications to: move data between buffers and arbitrary file
+	  descriptors; "copy" data between buffers; or copy data from userspace into
+	  buffers. If building an embedded system where no applications use these
+	  syscalls, you can disable this option to save space.
+
 config PCI_QUIRKS
 	default y
 	bool "Enable PCI quirk workarounds" if EXPERT
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index d2f5b00..25d5551 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -170,6 +170,14 @@ cond_syscall(sys_fstat);
 cond_syscall(sys_stat);
 cond_syscall(sys_uname);
 cond_syscall(sys_olduname);
+cond_syscall(sys_vmsplice);
+cond_syscall(sys_splice);
+cond_syscall(sys_tee);
+cond_syscall(sys_sendfile);
+cond_syscall(sys_sendfile64);
+cond_syscall(compat_sys_vmsplice);
+cond_syscall(compat_sys_sendfile);
+cond_syscall(compat_sys_sendfile64);
 
 /* arch-specific weak syscall entries */
 cond_syscall(sys_pciconfig_read);
-- 
2.1.0

^ permalink raw reply related

* [PATCH net-next 0/3] net: Remote checksum offload for VXLAN
From: Tom Herbert @ 2014-11-24 23:52 UTC (permalink / raw)
  To: davem, netdev

This patch set adds support for remote checksum offload in VXLAN.

The remote checksum offload is generalized by creating a common
function (remcsum_adjust) that does the work of modifying the
checksum in remote checksum offload. This function can be called
from normal or GRO path. GUE was modified to use this function.

To support RCO is VXLAN we use the 9th bit in the reserved
flags to indicated remote checksum offload. The start and offset
values are encoded n a compressed form in the low order (reserved)
byte of the vni field.

Remote checksum offload is described in
https://tools.ietf.org/html/draft-herbert-remotecsumoffload-01

Tested by running 200 TCP_STREAM connections with VXLAN (over IPv4).

With UDP checksums and Remote Checksum Offload
  IPv4
      Client
        11.84% CPU utilization
      Server
        12.96% CPU utilization
      9197 Mbps
  IPv6
      Client
        12.46% CPU utilization
      Server
        14.48% CPU utilization
      8963 Mbps

With UDP checksums, no remote checksum offload
  IPv4
      Client
        15.67% CPU utilization
      Server
        14.83% CPU utilization
      9094 Mbps
  IPv6
      Client
        16.21% CPU utilization
      Server
        14.32% CPU utilization
      9058 Mbps
 
No UDP checksums
  IPv4
      Client
        15.03% CPU utilization
      Server
        23.09% CPU utilization
      9089 Mbps
  IPv6
      Client
        16.18% CPU utilization
      Server
        26.57% CPU utilization
       8954 Mbps

Tom Herbert (3):
  net: Add remcsum_adjust as common function for remote checksum offload
  gue: Call remcsum_adjust
  vxlan: Remote checksum offload

 drivers/net/vxlan.c          | 188 +++++++++++++++++++++++++++++++++++++++++--
 include/net/checksum.h       |  16 ++++
 include/net/vxlan.h          |   2 +
 include/uapi/linux/if_link.h |   1 +
 net/ipv4/fou.c               |  84 ++++---------------
 5 files changed, 216 insertions(+), 75 deletions(-)

-- 
2.1.0.rc2.206.gedb03e5

^ permalink raw reply

* [PATCH net-next 1/3] net: Add remcsum_adjust as common function for remote checksum offload
From: Tom Herbert @ 2014-11-24 23:52 UTC (permalink / raw)
  To: davem, netdev
In-Reply-To: <1416873150-12260-1-git-send-email-therbert@google.com>

This function does the work to update a checksum field as part of
remote checksum offload.

remcsum_adjust does the following:

1) Subtract out the calculated checksum from the beginning of the
   packet (ptr arg) to the start offset.
2) Adjust the checksum field indicated by offset based on the modified
   checksum value from above step.
3) Return the difference in the old checksum field value and the
   new one. The caller will use this to update skb->csum and NAPI csum.

Signed-off-by: Tom Herbert <therbert@google.com>
---
 include/net/checksum.h | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/include/net/checksum.h b/include/net/checksum.h
index 6465bae..e339a95 100644
--- a/include/net/checksum.h
+++ b/include/net/checksum.h
@@ -151,4 +151,20 @@ static inline void inet_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb,
 				 (__force __be32)to, pseudohdr);
 }
 
+static inline __wsum remcsum_adjust(void *ptr, __wsum csum,
+				    int start, int offset)
+{
+	__sum16 *psum = (__sum16 *)(ptr + offset);
+	__wsum delta;
+
+	/* Subtract out checksum up to start */
+	csum = csum_sub(csum, csum_partial(ptr, start, 0));
+
+	/* Set derived checksum in packet */
+	delta = csum_sub(csum_fold(csum), *psum);
+	*psum = csum_fold(csum);
+
+	return delta;
+}
+
 #endif
-- 
2.1.0.rc2.206.gedb03e5

^ permalink raw reply related

* [PATCH net-next 2/3] gue: Call remcsum_adjust
From: Tom Herbert @ 2014-11-24 23:52 UTC (permalink / raw)
  To: davem, netdev
In-Reply-To: <1416873150-12260-1-git-send-email-therbert@google.com>

Change remote checksum offload to call remcsum_adjust. This also
eliminates the optimization to skip an IP header as part of the
adjustment (really does not seem to be much of a win).

Signed-off-by: Tom Herbert <therbert@google.com>
---
 net/ipv4/fou.c | 84 ++++++++++++----------------------------------------------
 1 file changed, 17 insertions(+), 67 deletions(-)

diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c
index 3dfe982..b986298 100644
--- a/net/ipv4/fou.c
+++ b/net/ipv4/fou.c
@@ -64,15 +64,13 @@ static int fou_udp_recv(struct sock *sk, struct sk_buff *skb)
 }
 
 static struct guehdr *gue_remcsum(struct sk_buff *skb, struct guehdr *guehdr,
-				  void *data, int hdrlen, u8 ipproto)
+				  void *data, size_t hdrlen, u8 ipproto)
 {
 	__be16 *pd = data;
-	u16 start = ntohs(pd[0]);
-	u16 offset = ntohs(pd[1]);
-	u16 poffset = 0;
-	u16 plen;
-	__wsum csum, delta;
-	__sum16 *psum;
+	size_t start = ntohs(pd[0]);
+	size_t offset = ntohs(pd[1]);
+	size_t plen = hdrlen + max_t(size_t, offset + sizeof(u16), start);
+	__wsum delta;
 
 	if (skb->remcsum_offload) {
 		/* Already processed in GRO path */
@@ -80,35 +78,15 @@ static struct guehdr *gue_remcsum(struct sk_buff *skb, struct guehdr *guehdr,
 		return guehdr;
 	}
 
-	if (start > skb->len - hdrlen ||
-	    offset > skb->len - hdrlen - sizeof(u16))
-		return NULL;
-
-	if (unlikely(skb->ip_summed != CHECKSUM_COMPLETE))
-		__skb_checksum_complete(skb);
-
-	plen = hdrlen + offset + sizeof(u16);
 	if (!pskb_may_pull(skb, plen))
 		return NULL;
 	guehdr = (struct guehdr *)&udp_hdr(skb)[1];
 
-	if (ipproto == IPPROTO_IP && sizeof(struct iphdr) < plen) {
-		struct iphdr *ip = (struct iphdr *)(skb->data + hdrlen);
-
-		/* If next header happens to be IP we can skip that for the
-		 * checksum calculation since the IP header checksum is zero
-		 * if correct.
-		 */
-		poffset = ip->ihl * 4;
-	}
-
-	csum = csum_sub(skb->csum, skb_checksum(skb, poffset + hdrlen,
-						start - poffset - hdrlen, 0));
+	if (unlikely(skb->ip_summed != CHECKSUM_COMPLETE))
+		__skb_checksum_complete(skb);
 
-	/* Set derived checksum in packet */
-	psum = (__sum16 *)(skb->data + hdrlen + offset);
-	delta = csum_sub(csum_fold(csum), *psum);
-	*psum = csum_fold(csum);
+	delta = remcsum_adjust((void *)guehdr + hdrlen,
+			       skb->csum, start, offset);
 
 	/* Adjust skb->csum since we changed the packet */
 	skb->csum = csum_add(skb->csum, delta);
@@ -158,9 +136,6 @@ static int gue_udp_recv(struct sock *sk, struct sk_buff *skb)
 
 	ip_hdr(skb)->tot_len = htons(ntohs(ip_hdr(skb)->tot_len) - len);
 
-	/* Pull UDP header now, skb->data points to guehdr */
-	__skb_pull(skb, sizeof(struct udphdr));
-
 	/* Pull csum through the guehdr now . This can be used if
 	 * there is a remote checksum offload.
 	 */
@@ -188,7 +163,7 @@ static int gue_udp_recv(struct sock *sk, struct sk_buff *skb)
 	if (unlikely(guehdr->control))
 		return gue_control_message(skb, guehdr);
 
-	__skb_pull(skb, hdrlen);
+	__skb_pull(skb, sizeof(struct udphdr) + hdrlen);
 	skb_reset_transport_header(skb);
 
 	return -guehdr->proto_ctype;
@@ -248,24 +223,17 @@ static struct guehdr *gue_gro_remcsum(struct sk_buff *skb, unsigned int off,
 				      size_t hdrlen, u8 ipproto)
 {
 	__be16 *pd = data;
-	u16 start = ntohs(pd[0]);
-	u16 offset = ntohs(pd[1]);
-	u16 poffset = 0;
-	u16 plen;
-	void *ptr;
-	__wsum csum, delta;
-	__sum16 *psum;
+	size_t start = ntohs(pd[0]);
+	size_t offset = ntohs(pd[1]);
+	size_t plen = hdrlen + max_t(size_t, offset + sizeof(u16), start);
+	__wsum delta;
 
 	if (skb->remcsum_offload)
 		return guehdr;
 
-	if (start > skb_gro_len(skb) - hdrlen ||
-	    offset > skb_gro_len(skb) - hdrlen - sizeof(u16) ||
-	    !NAPI_GRO_CB(skb)->csum_valid || skb->remcsum_offload)
+	if (!NAPI_GRO_CB(skb)->csum_valid)
 		return NULL;
 
-	plen = hdrlen + offset + sizeof(u16);
-
 	/* Pull checksum that will be written */
 	if (skb_gro_header_hard(skb, off + plen)) {
 		guehdr = skb_gro_header_slow(skb, off + plen, off);
@@ -273,26 +241,8 @@ static struct guehdr *gue_gro_remcsum(struct sk_buff *skb, unsigned int off,
 			return NULL;
 	}
 
-	ptr = (void *)guehdr + hdrlen;
-
-	if (ipproto == IPPROTO_IP &&
-	    (hdrlen + sizeof(struct iphdr) < plen)) {
-		struct iphdr *ip = (struct iphdr *)(ptr + hdrlen);
-
-		/* If next header happens to be IP we can skip
-		 * that for the checksum calculation since the
-		 * IP header checksum is zero if correct.
-		 */
-		poffset = ip->ihl * 4;
-	}
-
-	csum = csum_sub(NAPI_GRO_CB(skb)->csum,
-			csum_partial(ptr + poffset, start - poffset, 0));
-
-	/* Set derived checksum in packet */
-	psum = (__sum16 *)(ptr + offset);
-	delta = csum_sub(csum_fold(csum), *psum);
-	*psum = csum_fold(csum);
+	delta = remcsum_adjust((void *)guehdr + hdrlen,
+			       NAPI_GRO_CB(skb)->csum, start, offset);
 
 	/* Adjust skb->csum since we changed the packet */
 	skb->csum = csum_add(skb->csum, delta);
-- 
2.1.0.rc2.206.gedb03e5

^ permalink raw reply related

* [PATCH net-next 3/3] vxlan: Remote checksum offload
From: Tom Herbert @ 2014-11-24 23:52 UTC (permalink / raw)
  To: davem, netdev
In-Reply-To: <1416873150-12260-1-git-send-email-therbert@google.com>

Add support for remote checksum offload in VXLAN. This commandeers a
reserved bit to indicate that RCO is being done, and uses the low order
reserved eight bits of the VNI to hold the start and offset values in a
compressed manner.

Start is encoded in the low order seven bits of VNI. This is start >> 1
so that the checksum start offset is 0-254 using even values only.
Checksum offset (transport checksum field) is indicated in the high
order bit in the low order byte of the VNI. If the bit is set, the
checksum field is for UDP (so offset = start + 6), else checksum
field is for TCP (so offset = start + 16). Only TCP and UDP are
supported in this implementation.

Signed-off-by: Tom Herbert <therbert@google.com>
---
 drivers/net/vxlan.c          | 188 +++++++++++++++++++++++++++++++++++++++++--
 include/net/vxlan.h          |   2 +
 include/uapi/linux/if_link.h |   1 +
 3 files changed, 183 insertions(+), 8 deletions(-)

diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index e9f81d4..763f95e 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -65,7 +65,17 @@
 #define VXLAN_VID_MASK	(VXLAN_N_VID - 1)
 #define VXLAN_HLEN (sizeof(struct udphdr) + sizeof(struct vxlanhdr))
 
-#define VXLAN_FLAGS 0x08000000	/* struct vxlanhdr.vx_flags required value. */
+#define VXLAN_F_REQ	htonl(0x08000000) /* Required VXLAN flag */
+#define VXLAN_F_RCO	htonl(0x00400000) /* Remote checksum offload */
+
+#define VXLAN_MANDATORY_FLAGS (VXLAN_F_REQ)
+#define VXLAN_ALL_FLAGS (VXLAN_F_REQ | VXLAN_F_RCO)
+
+#define VXLAN_RCO_MASK	0x7f	/* Last byte of vni field */
+#define VXLAN_RCO_UDP	0x80	/* Indicate UDP RCO (TCP when not set *) */
+#define VXLAN_RCO_SHIFT	1	/* Left shift of start */
+#define VXLAN_RCO_SHIFT_MASK ((1 << VXLAN_RCO_SHIFT) - 1)
+#define VXLAN_MAX_REMCSUM_START (VXLAN_RCO_MASK << VXLAN_RCO_SHIFT)
 
 /* UDP port for VXLAN traffic.
  * The IANA assigned port is 4789, but the Linux default is 8472
@@ -545,6 +555,46 @@ static int vxlan_fdb_append(struct vxlan_fdb *f,
 	return 1;
 }
 
+static struct vxlanhdr *vxlan_gro_remcsum(struct sk_buff *skb,
+					  unsigned int off,
+					  struct vxlanhdr *vh, size_t hdrlen,
+					  u32 data)
+{
+	size_t start, offset, plen;
+	__wsum delta;
+
+	if (skb->remcsum_offload)
+		return vh;
+
+	if (!NAPI_GRO_CB(skb)->csum_valid)
+		return NULL;
+
+	start = (data & VXLAN_RCO_MASK) << VXLAN_RCO_SHIFT;
+	offset = start + ((data & VXLAN_RCO_UDP) ?
+			  offsetof(struct udphdr, check) :
+			  offsetof(struct tcphdr, check));
+
+	plen = hdrlen + offset + sizeof(u16);
+
+	/* Pull checksum that will be written */
+	if (skb_gro_header_hard(skb, off + plen)) {
+		vh = skb_gro_header_slow(skb, off + plen, off);
+		if (!vh)
+			return NULL;
+	}
+
+	delta = remcsum_adjust((void *)vh + hdrlen,
+			       NAPI_GRO_CB(skb)->csum, start, offset);
+
+	/* Adjust skb->csum since we changed the packet */
+	skb->csum = csum_add(skb->csum, delta);
+	NAPI_GRO_CB(skb)->csum = csum_add(NAPI_GRO_CB(skb)->csum, delta);
+
+	skb->remcsum_offload = 1;
+
+	return vh;
+}
+
 static struct sk_buff **vxlan_gro_receive(struct sk_buff **head, struct sk_buff *skb)
 {
 	struct sk_buff *p, **pp = NULL;
@@ -566,6 +616,14 @@ static struct sk_buff **vxlan_gro_receive(struct sk_buff **head, struct sk_buff
 	skb_gro_pull(skb, sizeof(struct vxlanhdr)); /* pull vxlan header */
 	skb_gro_postpull_rcsum(skb, vh, sizeof(struct vxlanhdr));
 
+	if (vh->vx_flags & VXLAN_F_RCO) {
+		vh = vxlan_gro_remcsum(skb, off_vx, vh, sizeof(struct vxlanhdr),
+				       ntohl(vh->vx_vni));
+
+		if (!vh)
+			goto out;
+	}
+
 	off_eth = skb_gro_offset(skb);
 	hlen = off_eth + sizeof(*eh);
 	eh   = skb_gro_header_fast(skb, off_eth);
@@ -1131,6 +1189,42 @@ static void vxlan_igmp_leave(struct work_struct *work)
 	dev_put(vxlan->dev);
 }
 
+static struct vxlanhdr *vxlan_remcsum(struct sk_buff *skb, struct vxlanhdr *vh,
+				      size_t hdrlen, u32 data)
+{
+	size_t start, offset, plen;
+	__wsum delta;
+
+	if (skb->remcsum_offload) {
+		/* Already processed in GRO path */
+		skb->remcsum_offload = 0;
+		return vh;
+	}
+
+	start = (data & VXLAN_RCO_MASK) << VXLAN_RCO_SHIFT;
+	offset = start + ((data & VXLAN_RCO_UDP) ?
+			  offsetof(struct udphdr, check) :
+			  offsetof(struct tcphdr, check));
+
+	plen = hdrlen + offset + sizeof(u16);
+
+	if (!pskb_may_pull(skb, plen))
+		return NULL;
+
+	vh = (struct vxlanhdr *)(udp_hdr(skb) + 1);
+
+	if (unlikely(skb->ip_summed != CHECKSUM_COMPLETE))
+		__skb_checksum_complete(skb);
+
+	delta = remcsum_adjust((void *)vh + hdrlen,
+			       skb->csum, start, offset);
+
+	/* Adjust skb->csum since we changed the packet */
+	skb->csum = csum_add(skb->csum, delta);
+
+	return vh;
+}
+
 /* Callback from net/ipv4/udp.c to receive packets */
 static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
 {
@@ -1143,8 +1237,8 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
 
 	/* Return packets with reserved bits set */
 	vxh = (struct vxlanhdr *)(udp_hdr(skb) + 1);
-	if (vxh->vx_flags != htonl(VXLAN_FLAGS) ||
-	    (vxh->vx_vni & htonl(0xff))) {
+	if ((vxh->vx_flags & VXLAN_MANDATORY_FLAGS) != VXLAN_MANDATORY_FLAGS ||
+	    (vxh->vx_flags & ~VXLAN_ALL_FLAGS)) {
 		netdev_dbg(skb->dev, "invalid vxlan flags=%#x vni=%#x\n",
 			   ntohl(vxh->vx_flags), ntohl(vxh->vx_vni));
 		goto error;
@@ -1152,6 +1246,14 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
 
 	if (iptunnel_pull_header(skb, VXLAN_HLEN, htons(ETH_P_TEB)))
 		goto drop;
+	vxh = (struct vxlanhdr *)(udp_hdr(skb) + 1);
+
+	if (vxh->vx_flags & VXLAN_F_RCO) {
+		vxh = vxlan_remcsum(skb, vxh, sizeof(struct vxlanhdr),
+				    ntohl(vxh->vx_vni));
+		if (!vxh)
+			goto drop;
+	}
 
 	vs = rcu_dereference_sk_user_data(sk);
 	if (!vs)
@@ -1577,8 +1679,23 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs,
 	int min_headroom;
 	int err;
 	bool udp_sum = !udp_get_no_check6_tx(vs->sock->sk);
+	int type = udp_sum ? SKB_GSO_UDP_TUNNEL_CSUM : SKB_GSO_UDP_TUNNEL;
+	u16 hdrlen = sizeof(struct vxlanhdr);
+
+	if ((vs->flags & VXLAN_F_REMCSUM) &&
+	    skb->ip_summed == CHECKSUM_PARTIAL) {
+		int csum_start = skb_checksum_start_offset(skb);
+
+		if (csum_start <= VXLAN_MAX_REMCSUM_START &&
+		    !(csum_start & VXLAN_RCO_SHIFT_MASK) &&
+		    (skb->csum_offset == offsetof(struct udphdr, check) ||
+		     skb->csum_offset == offsetof(struct tcphdr, check))) {
+			udp_sum = false;
+			type |= SKB_GSO_TUNNEL_REMCSUM;
+		}
+	}
 
-	skb = udp_tunnel_handle_offloads(skb, udp_sum);
+	skb = iptunnel_handle_offloads(skb, udp_sum, type);
 	if (IS_ERR(skb))
 		return -EINVAL;
 
@@ -1598,9 +1715,25 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs,
 		return -ENOMEM;
 
 	vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
-	vxh->vx_flags = htonl(VXLAN_FLAGS);
+	vxh->vx_flags = VXLAN_MANDATORY_FLAGS;
 	vxh->vx_vni = vni;
 
+	if (type & SKB_GSO_TUNNEL_REMCSUM) {
+		u32 data = (skb_checksum_start_offset(skb) - hdrlen) >>
+			   VXLAN_RCO_SHIFT;
+
+		if (skb->csum_offset == offsetof(struct udphdr, check))
+			data |= VXLAN_RCO_UDP;
+
+		vxh->vx_vni |= htonl(data);
+		vxh->vx_flags |= VXLAN_F_RCO;
+
+		if (!skb_is_gso(skb)) {
+			skb->ip_summed = CHECKSUM_NONE;
+			skb->encapsulation = 0;
+		}
+	}
+
 	skb_set_inner_protocol(skb, htons(ETH_P_TEB));
 
 	udp_tunnel6_xmit_skb(vs->sock, dst, skb, dev, saddr, daddr, prio,
@@ -1618,8 +1751,23 @@ int vxlan_xmit_skb(struct vxlan_sock *vs,
 	int min_headroom;
 	int err;
 	bool udp_sum = !vs->sock->sk->sk_no_check_tx;
+	int type = udp_sum ? SKB_GSO_UDP_TUNNEL_CSUM : SKB_GSO_UDP_TUNNEL;
+	u16 hdrlen = sizeof(struct vxlanhdr);
+
+	if ((vs->flags & VXLAN_F_REMCSUM) &&
+	    skb->ip_summed == CHECKSUM_PARTIAL) {
+		int csum_start = skb_checksum_start_offset(skb);
+
+		if (csum_start <= VXLAN_MAX_REMCSUM_START &&
+		    !(csum_start & VXLAN_RCO_SHIFT_MASK) &&
+		    (skb->csum_offset == offsetof(struct udphdr, check) ||
+		     skb->csum_offset == offsetof(struct tcphdr, check))) {
+			udp_sum = false;
+			type |= SKB_GSO_TUNNEL_REMCSUM;
+		}
+	}
 
-	skb = udp_tunnel_handle_offloads(skb, udp_sum);
+	skb = iptunnel_handle_offloads(skb, udp_sum, type);
 	if (IS_ERR(skb))
 		return -EINVAL;
 
@@ -1637,9 +1785,25 @@ int vxlan_xmit_skb(struct vxlan_sock *vs,
 		return -ENOMEM;
 
 	vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
-	vxh->vx_flags = htonl(VXLAN_FLAGS);
+	vxh->vx_flags = VXLAN_MANDATORY_FLAGS;
 	vxh->vx_vni = vni;
 
+	if (type & SKB_GSO_TUNNEL_REMCSUM) {
+		u32 data = (skb_checksum_start_offset(skb) - hdrlen) >>
+			   VXLAN_RCO_SHIFT;
+
+		if (skb->csum_offset == offsetof(struct udphdr, check))
+			data |= VXLAN_RCO_UDP;
+
+		vxh->vx_vni |= htonl(data);
+		vxh->vx_flags |= VXLAN_F_RCO;
+
+		if (!skb_is_gso(skb)) {
+			skb->ip_summed = CHECKSUM_NONE;
+			skb->encapsulation = 0;
+		}
+	}
+
 	skb_set_inner_protocol(skb, htons(ETH_P_TEB));
 
 	return udp_tunnel_xmit_skb(vs->sock, rt, skb, src, dst, tos,
@@ -2229,6 +2393,7 @@ static const struct nla_policy vxlan_policy[IFLA_VXLAN_MAX + 1] = {
 	[IFLA_VXLAN_UDP_CSUM]	= { .type = NLA_U8 },
 	[IFLA_VXLAN_UDP_ZERO_CSUM6_TX]	= { .type = NLA_U8 },
 	[IFLA_VXLAN_UDP_ZERO_CSUM6_RX]	= { .type = NLA_U8 },
+	[IFLA_VXLAN_REMCSUM]	= { .type = NLA_U8 },
 };
 
 static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[])
@@ -2350,6 +2515,7 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, __be16 port,
 	atomic_set(&vs->refcnt, 1);
 	vs->rcv = rcv;
 	vs->data = data;
+	vs->flags = flags;
 
 	/* Initialize the vxlan udp offloads structure */
 	vs->udp_offloads.port = port;
@@ -2547,6 +2713,9 @@ static int vxlan_newlink(struct net *net, struct net_device *dev,
 	    nla_get_u8(data[IFLA_VXLAN_UDP_ZERO_CSUM6_RX]))
 		vxlan->flags |= VXLAN_F_UDP_ZERO_CSUM6_RX;
 
+	if (data[IFLA_VXLAN_REMCSUM] && nla_get_u8(data[IFLA_VXLAN_REMCSUM]))
+		vxlan->flags |= VXLAN_F_REMCSUM;
+
 	if (vxlan_find_vni(net, vni, use_ipv6 ? AF_INET6 : AF_INET,
 			   vxlan->dst_port)) {
 		pr_info("duplicate VNI %u\n", vni);
@@ -2615,6 +2784,7 @@ static size_t vxlan_get_size(const struct net_device *dev)
 		nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_UDP_CSUM */
 		nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_UDP_ZERO_CSUM6_TX */
 		nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_UDP_ZERO_CSUM6_RX */
+		nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_REMCSUM */
 		0;
 }
 
@@ -2680,7 +2850,9 @@ static int vxlan_fill_info(struct sk_buff *skb, const struct net_device *dev)
 	    nla_put_u8(skb, IFLA_VXLAN_UDP_ZERO_CSUM6_TX,
 			!!(vxlan->flags & VXLAN_F_UDP_ZERO_CSUM6_TX)) ||
 	    nla_put_u8(skb, IFLA_VXLAN_UDP_ZERO_CSUM6_RX,
-			!!(vxlan->flags & VXLAN_F_UDP_ZERO_CSUM6_RX)))
+			!!(vxlan->flags & VXLAN_F_UDP_ZERO_CSUM6_RX)) ||
+	    nla_put_u8(skb, IFLA_VXLAN_REMCSUM,
+			!!(vxlan->flags & VXLAN_F_REMCSUM)))
 		goto nla_put_failure;
 
 	if (nla_put(skb, IFLA_VXLAN_PORT_RANGE, sizeof(ports), &ports))
diff --git a/include/net/vxlan.h b/include/net/vxlan.h
index 57cccd0..652e0dc 100644
--- a/include/net/vxlan.h
+++ b/include/net/vxlan.h
@@ -28,6 +28,7 @@ struct vxlan_sock {
 	struct hlist_head vni_list[VNI_HASH_SIZE];
 	atomic_t	  refcnt;
 	struct udp_offload udp_offloads;
+	u32		  flags;
 };
 
 #define VXLAN_F_LEARN			0x01
@@ -39,6 +40,7 @@ struct vxlan_sock {
 #define VXLAN_F_UDP_CSUM		0x40
 #define VXLAN_F_UDP_ZERO_CSUM6_TX	0x80
 #define VXLAN_F_UDP_ZERO_CSUM6_RX	0x100
+#define VXLAN_F_REMCSUM			0x200
 
 struct vxlan_sock *vxlan_sock_add(struct net *net, __be16 port,
 				  vxlan_rcv_t *rcv, void *data,
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 7072d83..d9e31e2 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -353,6 +353,7 @@ enum {
 	IFLA_VXLAN_UDP_CSUM,
 	IFLA_VXLAN_UDP_ZERO_CSUM6_TX,
 	IFLA_VXLAN_UDP_ZERO_CSUM6_RX,
+	IFLA_VXLAN_REMCSUM,
 	__IFLA_VXLAN_MAX
 };
 #define IFLA_VXLAN_MAX	(__IFLA_VXLAN_MAX - 1)
-- 
2.1.0.rc2.206.gedb03e5

^ permalink raw reply related

* Re: [PATCH 2/2] sh_eth: Fix asynchronous external abort
From: Simon Horman @ 2014-11-25  0:10 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Yoshihiro Kaneko, netdev@vger.kernel.org, David S. Miller,
	Magnus Damm, Linux-sh list
In-Reply-To: <CAMuHMdVeB0DmTr-xNHnZsHWao78Mdfk87+hThmiRu7qyZHMKWA@mail.gmail.com>

On Mon, Nov 24, 2014 at 09:41:18AM +0100, Geert Uytterhoeven wrote:
> On Mon, Nov 24, 2014 at 2:18 AM, Simon Horman <horms@verge.net.au> wrote:
> > On Thu, Nov 13, 2014 at 04:02:15PM +0900, Yoshihiro Kaneko wrote:
> >> From: Mitsuhiro Kimura <mitsuhiro.kimura.kc@renesas.com>
> >>
> >> When clock is disabled, Ethernet register access raise Bus error.
> >
> > I have spoken with Kimura-san and the problem may be reproduced by
> > calling ethtool with -s of -G while the network interface is down.
> >
> > e.g.:
> > ifconfig eth0 down
> > ethtool -G eth0 rx 512
> 
> That makes sense.
> 
> I think it would be good to add the reproduction steps to the commit message.

Yes, I agree entirely.

> > I have confirmed that the problem above appears in net-next
> > and appears to be resolved with this patch and the previous on
> > in this series (which seems to be a dependency) applied.
> 
> Gr{oetje,eeting}s,
> 
>                         Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                 -- Linus Torvalds
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sh" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply

* Re: [PATCH v4 3/7] fs/splice: support compiling out splice-family syscalls
From: Josh Triplett @ 2014-11-25  0:49 UTC (permalink / raw)
  To: Pieter Smith
  Cc: 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-fsdevel,
	open list, "open
In-Reply-To: <1416870079-15254-4-git-send-email-pieter@boesman.nl>

On Tue, Nov 25, 2014 at 12:01:02AM +0100, Pieter Smith wrote:
> Many embedded systems will not need the splice-family syscalls (splice,
> vmsplice, tee and sendfile). Omitting them saves space.  This adds a new EXPERT
> config option CONFIG_SYSCALL_SPLICE (default y) to support compiling them out.
> 
> The goal is to completely compile out fs/splice along with the syscalls. To
> achieve this, the remaining patch-set will deal with fs/splice exports. As far
> as possible, the impact on other device drivers will be minimized so as to
> reduce the overal maintenance burden of CONFIG_SYSCALL_SPLICE.
> 
> The use of exported functions will be solved by transparently mocking them out
> with static inlines. Uses of the exported pipe_buf_operations struct however
> require direct modification in fs/fuse and net/core. The next two patches will
> deal with this. A macro is defined that will assist with NULL'ing out callbacks
> when CONFIG_SYSCALL_SPLICE is undefined: __splice_p().

This message needs updating, since the patch series doesn't introduce or
use __splice_p anymore.

> Once all exports are solved, fs/splice can be compiled out.
> 
> The bloat benefit of this patch given a tinyconfig is:
> 
> add/remove: 0/16 grow/shrink: 2/5 up/down: 114/-3693 (-3579)
> function                                     old     new   delta
> splice_direct_to_actor                       348     416     +68
> splice_to_pipe                               371     417     +46
> splice_from_pipe_next                        107     106      -1
> fdput                                         11       -     -11
> signal_pending                                39      26     -13
> fdget                                         56      42     -14
> user_page_pipe_buf_ops                        20       -     -20
> user_page_pipe_buf_steal                      25       -     -25
> file_end_write                                58      29     -29
> file_start_write                              68      34     -34
> pipe_to_user                                  43       -     -43
> wakeup_pipe_readers                           54       -     -54
> do_splice_to                                  87       -     -87
> ipipe_prep.part                               92       -     -92
> opipe_prep.part                              119       -    -119
> sys_sendfile                                 122       -    -122
> sys_sendfile64                               126       -    -126
> sys_vmsplice                                 137       -    -137
> vmsplice_to_user                             205       -    -205
> sys_tee                                      491       -    -491
> do_sendfile                                  492       -    -492
> vmsplice_to_pipe                             558       -    -558
> sys_splice                                  1020       -   -1020
> 
> Signed-off-by: Pieter Smith <pieter@boesman.nl>
> ---
>  fs/splice.c     |  2 ++
>  init/Kconfig    | 10 ++++++++++
>  kernel/sys_ni.c |  8 ++++++++
>  3 files changed, 20 insertions(+)
> 
> diff --git a/fs/splice.c b/fs/splice.c
> index 44b201b..7c4c695 100644
> --- a/fs/splice.c
> +++ b/fs/splice.c
> @@ -1316,6 +1316,7 @@ 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);
> @@ -2200,4 +2201,5 @@ 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/init/Kconfig b/init/Kconfig
> index d811d5f..dec9819 100644
> --- a/init/Kconfig
> +++ b/init/Kconfig
> @@ -1571,6 +1571,16 @@ config NTP
>  	  system clock to an NTP server, you can disable this option to save
>  	  space.
>  
> +config SYSCALL_SPLICE
> +	bool "Enable splice/vmsplice/tee/sendfile syscalls" if EXPERT
> +	default y
> +	help
> +	  This option enables the splice, vmsplice, tee and sendfile syscalls. These
> +	  are used by applications to: move data between buffers and arbitrary file
> +	  descriptors; "copy" data between buffers; or copy data from userspace into
> +	  buffers. If building an embedded system where no applications use these
> +	  syscalls, you can disable this option to save space.
> +
>  config PCI_QUIRKS
>  	default y
>  	bool "Enable PCI quirk workarounds" if EXPERT
> diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
> index d2f5b00..25d5551 100644
> --- a/kernel/sys_ni.c
> +++ b/kernel/sys_ni.c
> @@ -170,6 +170,14 @@ cond_syscall(sys_fstat);
>  cond_syscall(sys_stat);
>  cond_syscall(sys_uname);
>  cond_syscall(sys_olduname);
> +cond_syscall(sys_vmsplice);
> +cond_syscall(sys_splice);
> +cond_syscall(sys_tee);
> +cond_syscall(sys_sendfile);
> +cond_syscall(sys_sendfile64);
> +cond_syscall(compat_sys_vmsplice);
> +cond_syscall(compat_sys_sendfile);
> +cond_syscall(compat_sys_sendfile64);
>  
>  /* arch-specific weak syscall entries */
>  cond_syscall(sys_pciconfig_read);
> -- 
> 2.1.0
> 

^ permalink raw reply

* Re: [PATCH v4 0/7] kernel tinification: optionally compile out splice family of syscalls (splice, vmsplice, tee and sendfile)
From: Josh Triplett @ 2014-11-25  0:52 UTC (permalink / raw)
  To: Pieter Smith
  Cc: 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-fsdevel,
	open list, "open
In-Reply-To: <1416870079-15254-1-git-send-email-pieter@boesman.nl>

On Tue, Nov 25, 2014 at 12:00:59AM +0100, Pieter Smith wrote:
> REPO: https://github.com/smipi1/linux-tinification.git
> 
> BRANCH: tiny/config-syscall-splice
> 
> BACKGROUND: This patch-set forms part of the Linux Kernel Tinification effort (
>   https://tiny.wiki.kernel.org/).
> 
> GOAL: Support compiling out the splice family of syscalls (splice, vmsplice,
>   tee and sendfile) along with all supporting infrastructure if not needed.
>   Many embedded systems will not need the splice-family syscalls. Omitting them
>   saves space.
> 
> HISTORY:
>   PATCH v4:
>     - Drops __splice_p()
>     - Let nfsd fall back to non-splice support when splice is compiled out
>     - Style fixes
[...]
> RESULTS: A tinyconfig bloat-o-meter score for the entire patch-set:
> 
> add/remove: 0/41 grow/shrink: 5/7 up/down: 23/-8422 (-8399)

I replied to one patch with a minor nit in the commit message.  Other
than that, I don't see any obvious issues with this.

- Josh Triplett

^ permalink raw reply

* Re: Network throughput is reducedof in total bandwidth in Mips.
From: Eric Dumazet @ 2014-11-25  0:55 UTC (permalink / raw)
  To: Sadasivan Shaiju; +Cc: linux-kernel, netdev
In-Reply-To: <d1b4ee5706f2dcb796b53ffb41cad1f8@mail.gmail.com>

On Mon, 2014-11-24 at 14:31 -0800, Sadasivan Shaiju wrote:
> HI,
> 
> When  using iperf   with  small  buffers  there  is a performance
> degradation   for  3.10  kernel   from  2.6.32  kernel .   Using
> profiling  tools   I am getting  the  following  data.
> 
> 2.6.32   kerne  data
> ........
> samples  %        symbol name
> 160321   39.1122  r4k_wait
> 43731    10.6687  __do_softirq
> 27547     6.7204  cvm_oct_napi_poll_68
> 16569     4.0422  _raw_spin_unlock_irqrestore
> 12537     3.0586  cvm_oct_xmit
> 7362      1.7960  kfree
> 5916      1.4433  tcp_ack
> 5480      1.3369  net_rx_action
> 5353      1.3059  __copy_user_common
> 5097      1.2435  put_page
> 4447      1.0849  __kmalloc
> 4361      1.0639  kmem_cache_alloc
> 4359      1.0634  skb_segment
> 4309      1.0512  tcp_v4_rcv
> 4120      1.0051  __inet_lookup_established
> 4016      0.9798  ip_route_input
> 4010      0.9783  napi_complete
> 3766      0.9188  tcp_write_xmit
> 3297      0.8043  free_hot_cold_page
> 3189      0.7780  kmem_cache_free
> 
> 3.10  kernel  data
> .......
> samples  %        symbol name
> 186       8.6431  __do_softirq
> 127       5.9015  cvm_oct_napi_poll_68
> 80        3.7175  tcp_sendmsg
> 76        3.5316  tcp_write_xmit
> 72        3.3457  cvm_oct_xmit_lockless
> 71        3.2993  _raw_spin_lock_bh
> 48        2.2305  tcp_release_cb
> 47        2.1840  release_sock
> 44        2.0446  add_preempt_count
> 44        2.0446  tcp_transmit_skb
> 34        1.5799  skb_split
> 31        1.4405  sub_preempt_count
> 27        1.2546  dev_hard_start_xmit
> 25        1.1617  __srcu_read_lock
> 25        1.1617  skb_release_data
> 24        1.1152  tcp_ack
> 23        1.0688  __bzero
> 23        1.0688  _raw_spin_unlock_irqrestore
> 23        1.0688  ip_finish_output
> 22        1.0223  __copy_skb_header
> 21        0.9758  __kfree_skb
> 21        0.9758  ip_queue_xmit
> 
> Looks  like  mainly the  delay  is  causing   by  tcp_sendmsg()  and
> tcp_write_xmit()   from  the  stack .   However   if  the  buffer  is
> increased   to  default  (128k)  there  is  no  performance
> Degradation .  This is  happening  only    for  small  buffers.
> 
> When  iperf is    used   as  below    the  bandwidth  on  3.10 kernel  is
> only  around   600Mbps    compared   to  900Mbps   in  2.6.32  kernel.
> 
> ./iperf3 -c 10.162.103.131 -l 1500
> 
> When  iperf  is  ran  with  default  buffers  as  follows  the  bandwidth
> is same  in 3.10  kernel  and 2.6.32  kernel.
> 
> ./iperf3 -c 10.162.103.131
> 
> Please  let me know  if  there is any fixes  available for  this .
> --

CC netdev, where you can actually find some help ;)

Quite frankly, there are probably some reasons Octeon ethernet driver is
still in staging.

1) This REUSE_SKBUFFS_WITHOUT_FREE kludge is quite horrible... Dont know
if it was used in 2.6.32 and still used in 3.10 on your config.

2) TX completions seem to be delayed by undefined amount of time.
   TCP Small Queues was added in 3.6 so this driver problem could
explain a lower throughput.

You could try adding skb_orphan() into this driver...

diff --git a/drivers/staging/octeon/ethernet-tx.c b/drivers/staging/octeon/ethernet-tx.c
index 4e54d854021955868e2c602ac829b9b217960efd..85f42f32419aabcda28f1b2aa44e396a462b3fb2 100644
--- a/drivers/staging/octeon/ethernet-tx.c
+++ b/drivers/staging/octeon/ethernet-tx.c
@@ -175,6 +175,7 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev)
 	 */
 	prefetch(priv);
 
+	skb_orphan(skb);
 	/*
 	 * The check on CVMX_PKO_QUEUES_PER_PORT_* is designed to
 	 * completely remove "qos" in the event neither interface

^ permalink raw reply related

* Re: [PATCH net-next 3/3] vxlan: Remote checksum offload
From: Jesse Gross @ 2014-11-25  1:06 UTC (permalink / raw)
  To: Tom Herbert; +Cc: David Miller, netdev
In-Reply-To: <1416873150-12260-4-git-send-email-therbert@google.com>

On Mon, Nov 24, 2014 at 3:52 PM, Tom Herbert <therbert@google.com> wrote:
> Add support for remote checksum offload in VXLAN. This commandeers a
> reserved bit to indicate that RCO is being done, and uses the low order
> reserved eight bits of the VNI to hold the start and offset values in a
> compressed manner.

Why do you think that this is OK for you to do? It's clear that there
is no consensus for this (and in fact there are other proposals that
use that bit in a different way).

^ permalink raw reply

* Re: [PATCH net_test_tools] route_bench: Fix bug in DST_ITERATE option
From: Vijay Subramanian @ 2014-11-25  1:18 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20141124.160932.1535765335085310139.davem@davemloft.net>

>> Signed-off-by: Vijay Subramanian <subramanian.vijay@gmail.com>
>
> This does not apply to the 'net' tree.

David,

The patch was targeted not against 'net' tree but against  test suite
at  https://git.kernel.org/pub/scm/linux/kernel/git/davem/net_test_tools.git
as indicated in subject. Would you like me to resubmit this making it
clear in commit log too?

-vijay

^ permalink raw reply


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