* Re: Let's do P4
From: Jiri Pirko @ 2016-10-31 17:12 UTC (permalink / raw)
To: John Fastabend
Cc: Alexei Starovoitov, Thomas Graf, Jakub Kicinski, netdev, davem,
jhs, roopa, simon.horman, ast, daniel, prem, hannes, jbenc, tom,
mattyk, idosch, eladr, yotamg, nogahf, ogerlitz, linville, andy,
f.fainelli, dsa, vivien.didelot, andrew, ivecera,
Maciej Żenczykowski
In-Reply-To: <58177712.4000208@gmail.com>
Mon, Oct 31, 2016 at 05:53:38PM CET, john.fastabend@gmail.com wrote:
>On 16-10-31 02:39 AM, Jiri Pirko wrote:
>> Sun, Oct 30, 2016 at 11:39:05PM CET, alexei.starovoitov@gmail.com wrote:
>>> On Sun, Oct 30, 2016 at 05:38:36PM +0100, Jiri Pirko wrote:
>>>> Sun, Oct 30, 2016 at 11:26:49AM CET, tgraf@suug.ch wrote:
>>>>> On 10/30/16 at 08:44am, Jiri Pirko wrote:
>>>>>> Sat, Oct 29, 2016 at 06:46:21PM CEST, john.fastabend@gmail.com wrote:
>>>>>>> On 16-10-29 07:49 AM, Jakub Kicinski wrote:
>>>>>>>> On Sat, 29 Oct 2016 09:53:28 +0200, Jiri Pirko wrote:
>>>>>>>>> Hi all.
>>>>>>>>>
>>>
>>> sorry for delay. travelling to KS, so probably missed something in
>>> this thread and comments can be totally off...
>>>
>>> the subject "let's do P4" is imo misleading, since it reads like
>>> we don't do P4 at the moment, whereas the opposite is true.
>>> Several p4->bpf compilers is a proof.
>>
>> We don't do p4 in kernel now, we don't do p4 offloading now. That is
>> the reason I started this discussion.
>>
>
>The point here is P4 is a high level language likely we will never "do"
>P4 in the kernel nor offload it. P4 translates to eBPF and runs in
>kernel just fine. This can be offloaded to some devices but as you
>point out is challenging for a class of architecture to offload.
>
>Also simple P4 programs can be offloaded into 'tc' cls_u32 for example
>and even cls_flower.
>
>>
>>>
>>>> The network world is divided into 2 general types of hw:
>>>> 1) network ASICs - network specific silicon, containing things like TCAM
>>>> These ASICs are suitable to be programmed by P4.
>>>
>>> i think the opposite is the case in case of P4.
>>> when hw asic has tcam it's still far far away from being usable with P4
>>> which requires fully programmable protocol parser, arbitrary tables and so on.
>>> P4 doesn't even define TCAM as a table type. The p4 program can declare
>>> a desired algorithm of search in the table and compiler has to figure out
>>> what HW resources to use to satisfy such p4 program.
>>>
>>>> 2) network processors - basically a general purpose CPUs
>>>> These processors are suitable to be programmed by eBPF.
>>>
>>> I think this statement is also misleading, since it positions
>>> p4 and bpf as competitors whereas that's not the case.
>>> p4 is the language. bpf is an instruction set.
>>
>> I wanted to say that we are having 2 approaches in silicon, 2 different
>> paradigms. Sure you can do p4>bpf. But hard to do it the opposite way.
>>
>>
>>>
>>>> Exactly. Following drawing shows p4 pipeline setup for SW and Hw:
>>>>
>>>> |
>>>> | +--> ebpf engine
>>>> | |
>>>> | |
>>>> | compilerB
>>>> | ^
>>>> | |
>>>> p4src --> compilerA --> p4ast --TCNL--> cls_p4 --+-> driver -> compilerC -> HW
>>>> |
>>>> userspace | kernel
>>>> |
>>>
>>> frankly this diagram smells very much like kernel bypass to me,
>>
>> what? That is well defined kernel API, in-kernel sw consumer and offload
>> in driver. Same API for both.
>>
>> Alex, you have very odd sense about what's bypassing kernel. That kind
>> of freaks me out...
>>
>
>I think the issue with offloading a P4-AST will be how much work goes
>into mapping this onto any particular hardware instance. And how much
>of the P4 language feature set is exposed.
>
>For example I suspect MLX switch has a different pipeline than MLX NIC
>and even different variations of the product lines. The same goes for
>Intel pipeline in NIC and switch and different products in same line.
>
>If P4-ast describes the exact instance of the hardware its an easy task
>the map is 1:1 but isn't exactly portable. Taking an N table onto a M
>table pipeline on the other hand is a bit more work and requires various
>transformations to occur in the runtime API. I'm guessing the class of
>devices we are talking about here can not reconfigure themselves to
>match the P4-ast.
I believe we can assume that. the p4ast has to be generic as the
original p4source is. It would be a terrible mistake to couple it with
some specific hardware. I only want to use p4ast because it would be easy
parse in kernel, unlike p4source.
>
>In the naive implementation only pipelines that map 1:1 will work. Maybe
>this is what Alexei is noticing?
P4 is ment to program programable hw, not fixed pipeline.
>
>>
>>> since I cannot see how one can put the whole p4 language compiler
>>> into the driver, so this last step of p4ast->hw, I presume, will be
>>> done by firmware, which will be running full compiler in an embedded cpu
>>
>> In case of mlxsw, that compiler would be in driver.
>>
>>
>>> on the switch. To me that's precisely the kernel bypass, since we won't
>>> have a clue what HW capabilities actually are and won't be able to fine
>>> grain control them.
>>> Please correct me if I'm wrong.
>>
>> You are wrong. By your definition, everything has to be figured out in
>> driver and FW does nothing. Otherwise it could do "something else" and
>> that would be a bypass? Does not make any sense to me whatsoever.
>>
>>
>>>
>>>> Plus the thing I cannot imagine in the model you propose is table fillup.
>>>> For ebpf, you use maps. For p4 you would have to have a separate HW-only
>>>> API. This is very similar to the original John's Flow-API. And therefore
>>>> a kernel bypass.
>>>
>>> I think John's flow api is a better way to expose mellanox switch capabilities.
>>
>> We are under impression that p4 suits us nicely. But it is not about
>> us, it is about finding the common way to do this.
>>
>
>I'll just poke at my FlowAPI question again. For fixed ASICS what is
>the Flow-API missing. We have a few proof points that show it is both
>sufficient and usable for the handful of use cases we care about.
Yeah, it is most probably fine. Even for flex ASICs to some point. The
question is how it stands comparing to other alternatives, like p4
>
>>
>>> I also think it's not fair to call it 'bypass'. I see nothing in it
>>> that justify such 'swear word' ;)
>>
>> John's Flow-API was a kernel bypass. Why? It was a API specifically
>> designed to directly work with HW tables, without kernel being involved.
>
>I don't think that is a fair definition of HW bypass. The SKIP_SW flag
>does exactly that for 'tc' based offloads and it was not rejected.
No, no, no. You still have possibility to do the same thing in kernel,
same functionality, with the same API. That is a big difference.
>
>The _real_ reason that seems to have fallen out of this and other
>discussion is the Flow-API didn't provide an in-kernel translation into
>an emulated patch. Note we always had a usermode translation to eBPF.
>A secondary reason appears to be overhead of adding yet another netlink
>family.
Yeah. Maybe you remember, back then when Flow-API was being discussed,
I suggested to wrap it under TC as cls_xflows and cls_xflowsaction of
some sort and do in-kernel datapath implementation. I believe that after
that, it would be acceptable.
>
>>
>>
>>> The goal of flow api was to expose HW features to user space, so that
>>> user space can program it. For something simple as mellanox switch
>>> asic it fits perfectly well.
>>
>> Again, this is not mlx-asic-specific. And again, that is a kernel bypass.
>>
>>
>>> Unless I misunderstand the bigger goal of this discussion and it's
>>> about programming ezchip devices.
>>
>> No. For network processors, I believe that BPF is nicely offloadable, no
>> need to do the excercise for that.
>>
>>
>>>
>>> If the goal is to model hw tcam in the linux kernel then just introduce
>>> tcam bpf map type. It will be dog slow in user space, but it will
>>> match exactly what is happnening in the HW and user space can make
>>> sensible trade-offs.
>>
>> No, you got me completely wrong. This is not about the TCAM. This is
>> about differences in the 2 words (p4/bpf).
>> Again, for "p4-ish" devices, you have to translate BPF. And as you
>> noted, it's an instruction set. Very hard if not impossible to parse in
>> order to get back the original semantics.
>>
>
>I think in this discussion "p4-ish" devices means devices with multiple
>tables in a pipeline? Not devices that have programmable/configurable
>pipelines right? And if we get to talking about reconfigurable devices
>I believe this should be done out of band as it typically means
>reloading some ucode, etc.
I'm talking about both. But I think we should focus on reconfigurable
ones, as we probably won't see that much fixed ones in the future.
^ permalink raw reply
* Re: [PATCH net] ipv6: Don't use ufo handling on later transformed packets
From: David Miller @ 2016-10-31 17:12 UTC (permalink / raw)
To: jkbs; +Cc: netdev, hannes, fw
In-Reply-To: <1477473674-21702-1-git-send-email-jkbs@redhat.com>
From: Jakub Sitnicki <jkbs@redhat.com>
Date: Wed, 26 Oct 2016 11:21:14 +0200
> Similar to commit c146066ab802 ("ipv4: Don't use ufo handling on later
> transformed packets"), don't perform UFO on packets that will be IPsec
> transformed. To detect it we rely on the fact that headerlen in
> dst_entry is non-zero only for transformation bundles (xfrm_dst
> objects).
>
> Unwanted segmentation can be observed with a NETIF_F_UFO capable device,
> such as a dummy device:
>
> DEV=dum0 LEN=1493
>
> ip li add $DEV type dummy
> ip addr add fc00::1/64 dev $DEV nodad
> ip link set $DEV up
> ip xfrm policy add dir out src fc00::1 dst fc00::2 \
> tmpl src fc00::1 dst fc00::2 proto esp spi 1
> ip xfrm state add src fc00::1 dst fc00::2 \
> proto esp spi 1 enc 'aes' 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
>
> tcpdump -n -nn -i $DEV -t &
> socat /dev/zero,readbytes=$LEN udp6:[fc00::2]:$LEN
>
> tcpdump output before:
>
> IP6 fc00::1 > fc00::2: frag (0|1448) ESP(spi=0x00000001,seq=0x1), length 1448
> IP6 fc00::1 > fc00::2: frag (1448|48)
> IP6 fc00::1 > fc00::2: ESP(spi=0x00000001,seq=0x2), length 88
>
> ... and after:
>
> IP6 fc00::1 > fc00::2: frag (0|1448) ESP(spi=0x00000001,seq=0x1), length 1448
> IP6 fc00::1 > fc00::2: frag (1448|80)
>
> Fixes: e89e9cf539a2 ("[IPv4/IPv6]: UFO Scatter-gather approach")
>
> Signed-off-by: Jakub Sitnicki <jkbs@redhat.com>
> Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Applied, thank you.
^ permalink raw reply
* Re: [PATCH 00/12] xen: add common function for reading optional value
From: David Miller @ 2016-10-31 17:08 UTC (permalink / raw)
To: jgross
Cc: linux-fbdev, wei.liu2, linux-pci, netdev, tomi.valkeinen,
dmitry.torokhov, tpmdd, linux-kernel, jarkko.sakkinen, xen-devel,
jgunthorpe, tpmdd-devel, david.vrabel, linux-input, bhelgaas,
boris.ostrovsky, peterhuewe, paul.durrant, roger.pau
In-Reply-To: <1477932510-28594-1-git-send-email-jgross@suse.com>
From: Juergen Gross <jgross@suse.com>
Date: Mon, 31 Oct 2016 17:48:18 +0100
> There are multiple instances of code reading an optional unsigned
> parameter from Xenstore via xenbus_scanf(). Instead of repeating the
> same code over and over add a service function doing the job and
> replace the call of xenbus_scanf() with the call of the new function
> where appropriate.
As this seems to be a series that will go through some tree other
than mine, I assume the networking bits will be taken care of that
way.
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
^ permalink raw reply
* Re: [PATCH v2 net-next 1/5] bpf: Refactor cgroups code in prep for new type
From: David Ahern @ 2016-10-31 17:05 UTC (permalink / raw)
To: Daniel Mack, David Miller; +Cc: netdev, ast, daniel, maheshb, tgraf
In-Reply-To: <542e0d3e-2f57-96f9-1da1-b71e2c970395@zonque.org>
On 10/31/16 11:00 AM, Daniel Mack wrote:
> On 10/31/2016 05:58 PM, David Miller wrote:
>> From: David Ahern <dsa@cumulusnetworks.com>
>> Date: Wed, 26 Oct 2016 17:58:38 -0700
>>
>>> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
>>> index 6b62ee9a2f78..73da296c2125 100644
>>> --- a/include/uapi/linux/bpf.h
>>> +++ b/include/uapi/linux/bpf.h
>>> @@ -98,7 +98,7 @@ enum bpf_prog_type {
>>> BPF_PROG_TYPE_TRACEPOINT,
>>> BPF_PROG_TYPE_XDP,
>>> BPF_PROG_TYPE_PERF_EVENT,
>>> - BPF_PROG_TYPE_CGROUP_SKB,
>>> + BPF_PROG_TYPE_CGROUP,
>>> };
>>>
>>> enum bpf_attach_type {
>>
>> If we do this then the cgroup-bpf series should use this value rather than
>> changing it after-the-fact in your series here.
>>
>
> Yeah, I'm confused too. I changed that name in my v7 from
> BPF_PROG_TYPE_CGROUP_SOCK to BPF_PROG_TYPE_CGROUP_SKB on David's (Ahern)
> request. Why is it now renamed again?
Thomas pushed back on adding another program type in favor of using subtypes. So this makes the program type generic to CGROUP and patch 2 in this v2 set added Mickaël's subtype patch with the socket mangling done that way in patch 3.
^ permalink raw reply
* Re: [PATCH v2 net-next 0/5] Add bpf support to set sk_bound_dev_if
From: David Miller @ 2016-10-31 17:01 UTC (permalink / raw)
To: dsa; +Cc: netdev, daniel, ast, daniel, maheshb, tgraf
In-Reply-To: <1477529922-4806-1-git-send-email-dsa@cumulusnetworks.com>
From: David Ahern <dsa@cumulusnetworks.com>
Date: Wed, 26 Oct 2016 17:58:37 -0700
> The recently added VRF support in Linux leverages the bind-to-device
> API for programs to specify an L3 domain for a socket. While
> SO_BINDTODEVICE has been around for ages, not every ipv4/ipv6 capable
> program has support for it. Even for those programs that do support it,
> the API requires processes to be started as root (CAP_NET_RAW) which
> is not desirable from a general security perspective.
>
> This patch set leverages Daniel Mack's work to attach bpf programs to
> a cgroup:
>
> https://www.mail-archive.com/netdev@vger.kernel.org/msg134028.html
>
> to provide a capability to set sk_bound_dev_if for all AF_INET{6}
> sockets opened by a process in a cgroup when the sockets are allocated.
>
> This capability enables running any program in a VRF context and is key
> to deploying Management VRF, a fundamental configuration for networking
> gear, with any Linux OS installation.
Ok, after some review I think I understand what's going on here.
It would initially seem simpler to just support forced sk_bound_dev_if
in cgroups. But I think I understand why you may have gone this way:
1) The cgroup-bpf code always has the cgroup hierarchy propagation
logic.
2) The may be use cases for doing things with other sock members.
With respect to #2, do you know of any such planned use cases already?
Also, any reason why you don't allow the cgroup bpf sk filter to return
an error code so that the sock creation could be cancelled if the eBPF
program desires that? It could be useful, I suppose.
Thanks.
^ permalink raw reply
* Re: [PATCH v2 net-next 1/5] bpf: Refactor cgroups code in prep for new type
From: Daniel Mack @ 2016-10-31 17:00 UTC (permalink / raw)
To: David Miller, dsa; +Cc: netdev, ast, daniel, maheshb, tgraf
In-Reply-To: <20161031.125801.874510216543796824.davem@davemloft.net>
On 10/31/2016 05:58 PM, David Miller wrote:
> From: David Ahern <dsa@cumulusnetworks.com>
> Date: Wed, 26 Oct 2016 17:58:38 -0700
>
>> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
>> index 6b62ee9a2f78..73da296c2125 100644
>> --- a/include/uapi/linux/bpf.h
>> +++ b/include/uapi/linux/bpf.h
>> @@ -98,7 +98,7 @@ enum bpf_prog_type {
>> BPF_PROG_TYPE_TRACEPOINT,
>> BPF_PROG_TYPE_XDP,
>> BPF_PROG_TYPE_PERF_EVENT,
>> - BPF_PROG_TYPE_CGROUP_SKB,
>> + BPF_PROG_TYPE_CGROUP,
>> };
>>
>> enum bpf_attach_type {
>
> If we do this then the cgroup-bpf series should use this value rather than
> changing it after-the-fact in your series here.
>
Yeah, I'm confused too. I changed that name in my v7 from
BPF_PROG_TYPE_CGROUP_SOCK to BPF_PROG_TYPE_CGROUP_SKB on David's (Ahern)
request. Why is it now renamed again?
Thanks,
Daniel
^ permalink raw reply
* Re: [PATCH v2 net-next 1/5] bpf: Refactor cgroups code in prep for new type
From: David Miller @ 2016-10-31 16:58 UTC (permalink / raw)
To: dsa; +Cc: netdev, daniel, ast, daniel, maheshb, tgraf
In-Reply-To: <1477529922-4806-2-git-send-email-dsa@cumulusnetworks.com>
From: David Ahern <dsa@cumulusnetworks.com>
Date: Wed, 26 Oct 2016 17:58:38 -0700
> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> index 6b62ee9a2f78..73da296c2125 100644
> --- a/include/uapi/linux/bpf.h
> +++ b/include/uapi/linux/bpf.h
> @@ -98,7 +98,7 @@ enum bpf_prog_type {
> BPF_PROG_TYPE_TRACEPOINT,
> BPF_PROG_TYPE_XDP,
> BPF_PROG_TYPE_PERF_EVENT,
> - BPF_PROG_TYPE_CGROUP_SKB,
> + BPF_PROG_TYPE_CGROUP,
> };
>
> enum bpf_attach_type {
If we do this then the cgroup-bpf series should use this value rather than
changing it after-the-fact in your series here.
^ permalink raw reply
* [RFC PATCH v2 3/5] ARM64: dts: meson-gxl: Add ethernet nodes with internal PHY
From: Neil Armstrong @ 2016-10-31 16:56 UTC (permalink / raw)
To: f.fainelli, khilman, carlo, andrew
Cc: Neil Armstrong, netdev, linux-amlogic, linux-arm-kernel,
linux-kernel, devicetree
In-Reply-To: <1477932987-27871-1-git-send-email-narmstrong@baylibre.com>
Add Ethernet node with Internal PHY selection for the Amlogic GXL SoCs
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 45 ++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
index d1bf381..71670c3 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
@@ -47,6 +47,24 @@
/ {
compatible = "amlogic,meson-gxl";
+
+
+};
+
+ðmac {
+ reg = <0x0 0xc9410000 0x0 0x10000
+ 0x0 0xc8834540 0x0 0x4>;
+
+ clocks = <&clkc CLKID_ETH>,
+ <&clkc CLKID_FCLK_DIV2>,
+ <&clkc CLKID_MPLL2>;
+ clock-names = "stmmaceth", "clkin0", "clkin1";
+
+ mdio0: mdio0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dwmac-mdio";
+ };
};
&aobus {
@@ -214,6 +232,33 @@
};
};
};
+
+ eth-phy-mux {
+ compatible = "mdio-mux-mmioreg", "mdio-mux";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0x55c 0x0 0x4>;
+ mux-mask = <0xffffffff>;
+ mdio-parent-bus = <&mdio0>;
+
+ internal_mdio: mdio@e40908ff {
+ reg = <0xe40908ff>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ internal_phy: ethernet-phy@8 {
+ compatible = "ethernet-phy-id0181.4400", "ethernet-phy-ieee802.3-c22";
+ reg = <8>;
+ max-speed = <100>;
+ };
+ };
+
+ external_mdio: mdio@2009087f {
+ reg = <0x2009087f>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
};
&hiubus {
--
1.9.1
^ permalink raw reply related
* [RFC PATCH v2 5/5] ARM64: dts: meson-gxl-s905x: Enable internal ethernet PHY
From: Neil Armstrong @ 2016-10-31 16:56 UTC (permalink / raw)
To: f.fainelli, khilman, carlo, andrew
Cc: Neil Armstrong, netdev, linux-amlogic, linux-arm-kernel,
linux-kernel, devicetree
In-Reply-To: <1477932987-27871-1-git-send-email-narmstrong@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
arch/arm64/boot/dts/amlogic/meson-gxl-s905x.dtsi | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x.dtsi
index 07f0e0b..08237ee 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x.dtsi
@@ -46,3 +46,9 @@
/ {
compatible = "amlogic,s905x", "amlogic,meson-gxl";
};
+
+/* S905X Only has access to its internal PHY */
+ðmac {
+ phy-mode = "rmii";
+ phy-handle = <&internal_phy>;
+};
--
1.9.1
^ permalink raw reply related
* [RFC PATCH v2 4/5] ARM64: dts: meson-gxl-p23x: Enable ethernet
From: Neil Armstrong @ 2016-10-31 16:56 UTC (permalink / raw)
To: f.fainelli, khilman, carlo, andrew
Cc: Neil Armstrong, netdev, linux-amlogic, linux-arm-kernel,
linux-kernel, devicetree
In-Reply-To: <1477932987-27871-1-git-send-email-narmstrong@baylibre.com>
Enable Ethernet on the p23x board, pinctrl attribute is only added for
the p230 board since the p231 only uses the Internal PHY.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts | 16 ++++++++++++++++
arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p231.dts | 6 ++++++
arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p23x.dtsi | 4 ++++
3 files changed, 26 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts
index 3dfaa37..a569286 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts
@@ -49,3 +49,19 @@
compatible = "amlogic,p230", "amlogic,s905d", "amlogic,meson-gxl";
model = "Amlogic Meson GXL (S905D) P230 Development Board";
};
+
+/* P230 has exclusive choice between internal or external PHY */
+ðmac {
+ pinctrl-0 = <ð_pins>;
+ pinctrl-names = "default";
+
+ phy-handle = <&external_phy>;
+};
+
+&external_mdio {
+ external_phy: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ max-speed = <1000>;
+ };
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p231.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p231.dts
index ade8d29..1cc8d49 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p231.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p231.dts
@@ -49,3 +49,9 @@
compatible = "amlogic,p231", "amlogic,s905d", "amlogic,meson-gxl";
model = "Amlogic Meson GXL (S905D) P231 Development Board";
};
+
+/* P231 has only internal PHY port */
+ðmac {
+ phy-mode = "rmii";
+ phy-handle = <&internal_phy>;
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p23x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p23x.dtsi
index bbe46a2..622ffbe 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p23x.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p23x.dtsi
@@ -182,3 +182,7 @@
clocks = <&clkc CLKID_FCLK_DIV4>;
clock-names = "clkin0";
};
+
+ðmac {
+ status = "okay";
+};
--
1.9.1
^ permalink raw reply related
* [RFC PATCH v2 2/5] net: phy: Add Meson GXL Internal PHY driver
From: Neil Armstrong @ 2016-10-31 16:56 UTC (permalink / raw)
To: f.fainelli, khilman, carlo, andrew
Cc: Neil Armstrong, netdev, linux-amlogic, linux-arm-kernel,
linux-kernel
In-Reply-To: <1477932987-27871-1-git-send-email-narmstrong@baylibre.com>
Add driver for the Internal RMII PHY found in the Amlogic Meson GXL SoCs.
This PHY seems to only implement some standard registers and need some
workarounds to provide autoneg values from vendor registers.
Some magic values are currently used to configure the PHY, and this a
temporary setup until clarification about these registers names and
registers fields are provided by Amlogic.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/net/phy/Kconfig | 5 +++
drivers/net/phy/Makefile | 1 +
drivers/net/phy/meson-gxl.c | 81 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 87 insertions(+)
create mode 100644 drivers/net/phy/meson-gxl.c
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 2651c8d..09342b6 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -226,6 +226,11 @@ config DP83867_PHY
---help---
Currently supports the DP83867 PHY.
+config MESON_GXL_PHY
+ tristate "Amlogic Meson GXL Internal PHY"
+ ---help---
+ Currently has a driver for the Amlogic Meson GXL Internal PHY
+
config FIXED_PHY
tristate "MDIO Bus/PHY emulation with fixed speed/link PHYs"
depends on PHYLIB
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index e58667d..1511b3e 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_MARVELL_PHY) += marvell.o
obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o
obj-$(CONFIG_MICREL_PHY) += micrel.o
obj-$(CONFIG_MICROCHIP_PHY) += microchip.o
+obj-$(CONFIG_MESON_GXL_PHY) += meson-gxl.o
obj-$(CONFIG_MICROSEMI_PHY) += mscc.o
obj-$(CONFIG_NATIONAL_PHY) += national.o
obj-$(CONFIG_QSEMI_PHY) += qsemi.o
diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c
new file mode 100644
index 0000000..1ea69b7
--- /dev/null
+++ b/drivers/net/phy/meson-gxl.c
@@ -0,0 +1,81 @@
+/*
+ * Amlogic Meson GXL Internal PHY Driver
+ *
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ * Copyright (C) 2016 BayLibre, SAS. All rights reserved.
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/phy.h>
+#include <linux/netdevice.h>
+
+static int meson_gxl_config_init(struct phy_device *phydev)
+{
+ /* Enable Analog and DSP register Bank access by */
+ phy_write(phydev, 0x14, 0x0000);
+ phy_write(phydev, 0x14, 0x0400);
+ phy_write(phydev, 0x14, 0x0000);
+ phy_write(phydev, 0x14, 0x0400);
+
+ /* Write Analog register 23 */
+ phy_write(phydev, 0x17, 0x8E0D);
+ phy_write(phydev, 0x14, 0x4417);
+
+ /* Enable fractional PLL */
+ phy_write(phydev, 0x17, 0x0005);
+ phy_write(phydev, 0x14, 0x5C1B);
+
+ /* Program fraction FR_PLL_DIV1 */
+ phy_write(phydev, 0x17, 0x029A);
+ phy_write(phydev, 0x14, 0x5C1D);
+
+ /* Program fraction FR_PLL_DIV1 */
+ phy_write(phydev, 0x17, 0xAAAA);
+ phy_write(phydev, 0x14, 0x5C1C);
+
+ return 0;
+}
+
+static struct phy_driver meson_gxl_phy[] = {
+ {
+ .phy_id = 0x01814400,
+ .phy_id_mask = 0xfffffff0,
+ .name = "Meson GXL Internal PHY",
+ .features = PHY_BASIC_FEATURES,
+ .flags = PHY_IS_INTERNAL,
+ .config_init = meson_gxl_config_init,
+ .config_aneg = genphy_config_aneg,
+ .aneg_done = genphy_aneg_done,
+ .read_status = genphy_read_status,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ },
+};
+
+static struct mdio_device_id __maybe_unused meson_gxl_tbl[] = {
+ { 0x01814400, 0xfffffff0 },
+ { }
+};
+
+module_phy_driver(meson_gxl_phy);
+
+MODULE_DEVICE_TABLE(mdio, meson_gxl_tbl);
+
+MODULE_DESCRIPTION("Amlogic Meson GXL Internal PHY driver");
+MODULE_AUTHOR("Baoqi wang");
+MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
+MODULE_LICENSE("GPL");
--
1.9.1
^ permalink raw reply related
* [RFC PATCH v2 1/5] net: mdio-mux-mmioreg: Add support for 16bit and 32bit register sizes
From: Neil Armstrong @ 2016-10-31 16:56 UTC (permalink / raw)
To: f.fainelli, khilman, carlo, andrew
Cc: Neil Armstrong, netdev, linux-amlogic, linux-arm-kernel,
linux-kernel, devicetree
In-Reply-To: <1477932987-27871-1-git-send-email-narmstrong@baylibre.com>
In order to support PHY switching on Amlogic GXL SoCs, add support for
16bit and 32bit registers sizes.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
.../devicetree/bindings/net/mdio-mux-mmioreg.txt | 4 +-
drivers/net/phy/mdio-mux-mmioreg.c | 60 +++++++++++++++++-----
2 files changed, 49 insertions(+), 15 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/mdio-mux-mmioreg.txt b/Documentation/devicetree/bindings/net/mdio-mux-mmioreg.txt
index 8516929..065e8bd 100644
--- a/Documentation/devicetree/bindings/net/mdio-mux-mmioreg.txt
+++ b/Documentation/devicetree/bindings/net/mdio-mux-mmioreg.txt
@@ -3,7 +3,7 @@ Properties for an MDIO bus multiplexer controlled by a memory-mapped device
This is a special case of a MDIO bus multiplexer. A memory-mapped device,
like an FPGA, is used to control which child bus is connected. The mdio-mux
node must be a child of the memory-mapped device. The driver currently only
-supports devices with eight-bit registers.
+supports devices with 8, 16 or 32-bit registers.
Required properties in addition to the generic multiplexer properties:
@@ -11,7 +11,7 @@ Required properties in addition to the generic multiplexer properties:
- reg : integer, contains the offset of the register that controls the bus
multiplexer. The size field in the 'reg' property is the size of
- register, and must therefore be 1.
+ register, and must therefore be 1, 2, or 4.
- mux-mask : integer, contains an eight-bit mask that specifies which
bits in the register control the actual bus multiplexer. The
diff --git a/drivers/net/phy/mdio-mux-mmioreg.c b/drivers/net/phy/mdio-mux-mmioreg.c
index d0bed52..6a33646 100644
--- a/drivers/net/phy/mdio-mux-mmioreg.c
+++ b/drivers/net/phy/mdio-mux-mmioreg.c
@@ -21,7 +21,8 @@
struct mdio_mux_mmioreg_state {
void *mux_handle;
phys_addr_t phys;
- uint8_t mask;
+ unsigned int iosize;
+ unsigned int mask;
};
/*
@@ -47,17 +48,47 @@ static int mdio_mux_mmioreg_switch_fn(int current_child, int desired_child,
struct mdio_mux_mmioreg_state *s = data;
if (current_child ^ desired_child) {
- void __iomem *p = ioremap(s->phys, 1);
- uint8_t x, y;
-
+ void __iomem *p = ioremap(s->phys, s->iosize);
if (!p)
return -ENOMEM;
- x = ioread8(p);
- y = (x & ~s->mask) | desired_child;
- if (x != y) {
- iowrite8((x & ~s->mask) | desired_child, p);
- pr_debug("%s: %02x -> %02x\n", __func__, x, y);
+ switch (s->iosize) {
+ case sizeof(uint8_t): {
+ uint8_t x, y;
+
+ x = ioread8(p);
+ y = (x & ~s->mask) | desired_child;
+ if (x != y) {
+ iowrite8((x & ~s->mask) | desired_child, p);
+ pr_debug("%s: %02x -> %02x\n", __func__, x, y);
+ }
+
+ break;
+ }
+ case sizeof(uint16_t): {
+ uint16_t x, y;
+
+ x = ioread16(p);
+ y = (x & ~s->mask) | desired_child;
+ if (x != y) {
+ iowrite16((x & ~s->mask) | desired_child, p);
+ pr_debug("%s: %04x -> %04x\n", __func__, x, y);
+ }
+
+ break;
+ }
+ case sizeof(uint32_t): {
+ uint32_t x, y;
+
+ x = ioread32(p);
+ y = (x & ~s->mask) | desired_child;
+ if (x != y) {
+ iowrite32((x & ~s->mask) | desired_child, p);
+ pr_debug("%s: %08x -> %08x\n", __func__, x, y);
+ }
+
+ break;
+ }
}
iounmap(p);
@@ -88,8 +119,11 @@ static int mdio_mux_mmioreg_probe(struct platform_device *pdev)
}
s->phys = res.start;
- if (resource_size(&res) != sizeof(uint8_t)) {
- dev_err(&pdev->dev, "only 8-bit registers are supported\n");
+ s->iosize = resource_size(&res);
+ if (s->iosize != sizeof(uint8_t) &&
+ s->iosize != sizeof(uint16_t) &&
+ s->iosize != sizeof(uint32_t)) {
+ dev_err(&pdev->dev, "only 8/16/32-bit registers are supported\n");
return -EINVAL;
}
@@ -98,8 +132,8 @@ static int mdio_mux_mmioreg_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "missing or invalid mux-mask property\n");
return -ENODEV;
}
- if (be32_to_cpup(iprop) > 255) {
- dev_err(&pdev->dev, "only 8-bit registers are supported\n");
+ if (be32_to_cpup(iprop) >= BIT(s->iosize * 8)) {
+ dev_err(&pdev->dev, "only 8/16/32-bit registers are supported\n");
return -EINVAL;
}
s->mask = be32_to_cpup(iprop);
--
1.9.1
^ permalink raw reply related
* [RFC PATCH v2 0/5] ARM64: Add Internal PHY support for Meson GXL
From: Neil Armstrong @ 2016-10-31 16:56 UTC (permalink / raw)
To: f.fainelli, khilman, carlo, andrew
Cc: devicetree, Neil Armstrong, netdev, linux-kernel, linux-amlogic,
linux-arm-kernel
The Amlogic Meson GXL SoCs have an internal RMII PHY that is muxed with the
external RGMII pins.
In order to support switching between the two PHYs links, extended registers
size for mdio-mux-mmioreg must be added.
Finally, the internal PHY is added in the GXL dtsi and support for each
board is added in intermediate board family dtsi or final dts.
This patchset depends on ARM64 dts patch at [1]
Changes since original RFC patchset at : [2]
- Remove meson8b experimental phy switching
- Switch to mdio-mux-mmioreg with extennded size support
- Add internal phy support for S905x and p231
- Add external PHY support for p230
[1] http://lkml.kernel.org/r/1477932286-27482-1-git-send-email-narmstrong@baylibre.com
[2] http://lkml.kernel.org/r/1477060838-14164-1-git-send-email-narmstrong@baylibre.com
Neil Armstrong (5):
net: mdio-mux-mmioreg: Add support for 16bit and 32bit register sizes
net: phy: Add Meson GXL Internal PHY driver
ARM64: dts: meson-gxl: Add ethernet nodes with internal PHY
ARM64: dts: meson-gxl-p23x: Enable ethernet
ARM64: dts: meson-gxl-s905x: Enable internal ethernet PHY
.../devicetree/bindings/net/mdio-mux-mmioreg.txt | 4 +-
.../boot/dts/amlogic/meson-gxl-s905d-p230.dts | 16 +++++
.../boot/dts/amlogic/meson-gxl-s905d-p231.dts | 6 ++
.../boot/dts/amlogic/meson-gxl-s905d-p23x.dtsi | 4 ++
arch/arm64/boot/dts/amlogic/meson-gxl-s905x.dtsi | 6 ++
arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 45 ++++++++++++
drivers/net/phy/Kconfig | 5 ++
drivers/net/phy/Makefile | 1 +
drivers/net/phy/mdio-mux-mmioreg.c | 60 ++++++++++++----
drivers/net/phy/meson-gxl.c | 81 ++++++++++++++++++++++
10 files changed, 213 insertions(+), 15 deletions(-)
create mode 100644 drivers/net/phy/meson-gxl.c
--
1.9.1
^ permalink raw reply
* Re: Let's do P4
From: John Fastabend @ 2016-10-31 16:53 UTC (permalink / raw)
To: Jiri Pirko, Alexei Starovoitov
Cc: Thomas Graf, Jakub Kicinski, netdev, davem, jhs, roopa,
simon.horman, ast, daniel, prem, hannes, jbenc, tom, mattyk,
idosch, eladr, yotamg, nogahf, ogerlitz, linville, andy,
f.fainelli, dsa, vivien.didelot, andrew, ivecera,
Maciej Żenczykowski
In-Reply-To: <20161031093922.GA2895@nanopsycho.orion>
On 16-10-31 02:39 AM, Jiri Pirko wrote:
> Sun, Oct 30, 2016 at 11:39:05PM CET, alexei.starovoitov@gmail.com wrote:
>> On Sun, Oct 30, 2016 at 05:38:36PM +0100, Jiri Pirko wrote:
>>> Sun, Oct 30, 2016 at 11:26:49AM CET, tgraf@suug.ch wrote:
>>>> On 10/30/16 at 08:44am, Jiri Pirko wrote:
>>>>> Sat, Oct 29, 2016 at 06:46:21PM CEST, john.fastabend@gmail.com wrote:
>>>>>> On 16-10-29 07:49 AM, Jakub Kicinski wrote:
>>>>>>> On Sat, 29 Oct 2016 09:53:28 +0200, Jiri Pirko wrote:
>>>>>>>> Hi all.
>>>>>>>>
>>
>> sorry for delay. travelling to KS, so probably missed something in
>> this thread and comments can be totally off...
>>
>> the subject "let's do P4" is imo misleading, since it reads like
>> we don't do P4 at the moment, whereas the opposite is true.
>> Several p4->bpf compilers is a proof.
>
> We don't do p4 in kernel now, we don't do p4 offloading now. That is
> the reason I started this discussion.
>
The point here is P4 is a high level language likely we will never "do"
P4 in the kernel nor offload it. P4 translates to eBPF and runs in
kernel just fine. This can be offloaded to some devices but as you
point out is challenging for a class of architecture to offload.
Also simple P4 programs can be offloaded into 'tc' cls_u32 for example
and even cls_flower.
>
>>
>>> The network world is divided into 2 general types of hw:
>>> 1) network ASICs - network specific silicon, containing things like TCAM
>>> These ASICs are suitable to be programmed by P4.
>>
>> i think the opposite is the case in case of P4.
>> when hw asic has tcam it's still far far away from being usable with P4
>> which requires fully programmable protocol parser, arbitrary tables and so on.
>> P4 doesn't even define TCAM as a table type. The p4 program can declare
>> a desired algorithm of search in the table and compiler has to figure out
>> what HW resources to use to satisfy such p4 program.
>>
>>> 2) network processors - basically a general purpose CPUs
>>> These processors are suitable to be programmed by eBPF.
>>
>> I think this statement is also misleading, since it positions
>> p4 and bpf as competitors whereas that's not the case.
>> p4 is the language. bpf is an instruction set.
>
> I wanted to say that we are having 2 approaches in silicon, 2 different
> paradigms. Sure you can do p4>bpf. But hard to do it the opposite way.
>
>
>>
>>> Exactly. Following drawing shows p4 pipeline setup for SW and Hw:
>>>
>>> |
>>> | +--> ebpf engine
>>> | |
>>> | |
>>> | compilerB
>>> | ^
>>> | |
>>> p4src --> compilerA --> p4ast --TCNL--> cls_p4 --+-> driver -> compilerC -> HW
>>> |
>>> userspace | kernel
>>> |
>>
>> frankly this diagram smells very much like kernel bypass to me,
>
> what? That is well defined kernel API, in-kernel sw consumer and offload
> in driver. Same API for both.
>
> Alex, you have very odd sense about what's bypassing kernel. That kind
> of freaks me out...
>
I think the issue with offloading a P4-AST will be how much work goes
into mapping this onto any particular hardware instance. And how much
of the P4 language feature set is exposed.
For example I suspect MLX switch has a different pipeline than MLX NIC
and even different variations of the product lines. The same goes for
Intel pipeline in NIC and switch and different products in same line.
If P4-ast describes the exact instance of the hardware its an easy task
the map is 1:1 but isn't exactly portable. Taking an N table onto a M
table pipeline on the other hand is a bit more work and requires various
transformations to occur in the runtime API. I'm guessing the class of
devices we are talking about here can not reconfigure themselves to
match the P4-ast.
In the naive implementation only pipelines that map 1:1 will work. Maybe
this is what Alexei is noticing?
>
>> since I cannot see how one can put the whole p4 language compiler
>> into the driver, so this last step of p4ast->hw, I presume, will be
>> done by firmware, which will be running full compiler in an embedded cpu
>
> In case of mlxsw, that compiler would be in driver.
>
>
>> on the switch. To me that's precisely the kernel bypass, since we won't
>> have a clue what HW capabilities actually are and won't be able to fine
>> grain control them.
>> Please correct me if I'm wrong.
>
> You are wrong. By your definition, everything has to be figured out in
> driver and FW does nothing. Otherwise it could do "something else" and
> that would be a bypass? Does not make any sense to me whatsoever.
>
>
>>
>>> Plus the thing I cannot imagine in the model you propose is table fillup.
>>> For ebpf, you use maps. For p4 you would have to have a separate HW-only
>>> API. This is very similar to the original John's Flow-API. And therefore
>>> a kernel bypass.
>>
>> I think John's flow api is a better way to expose mellanox switch capabilities.
>
> We are under impression that p4 suits us nicely. But it is not about
> us, it is about finding the common way to do this.
>
I'll just poke at my FlowAPI question again. For fixed ASICS what is
the Flow-API missing. We have a few proof points that show it is both
sufficient and usable for the handful of use cases we care about.
>
>> I also think it's not fair to call it 'bypass'. I see nothing in it
>> that justify such 'swear word' ;)
>
> John's Flow-API was a kernel bypass. Why? It was a API specifically
> designed to directly work with HW tables, without kernel being involved.
I don't think that is a fair definition of HW bypass. The SKIP_SW flag
does exactly that for 'tc' based offloads and it was not rejected.
The _real_ reason that seems to have fallen out of this and other
discussion is the Flow-API didn't provide an in-kernel translation into
an emulated patch. Note we always had a usermode translation to eBPF.
A secondary reason appears to be overhead of adding yet another netlink
family.
>
>
>> The goal of flow api was to expose HW features to user space, so that
>> user space can program it. For something simple as mellanox switch
>> asic it fits perfectly well.
>
> Again, this is not mlx-asic-specific. And again, that is a kernel bypass.
>
>
>> Unless I misunderstand the bigger goal of this discussion and it's
>> about programming ezchip devices.
>
> No. For network processors, I believe that BPF is nicely offloadable, no
> need to do the excercise for that.
>
>
>>
>> If the goal is to model hw tcam in the linux kernel then just introduce
>> tcam bpf map type. It will be dog slow in user space, but it will
>> match exactly what is happnening in the HW and user space can make
>> sensible trade-offs.
>
> No, you got me completely wrong. This is not about the TCAM. This is
> about differences in the 2 words (p4/bpf).
> Again, for "p4-ish" devices, you have to translate BPF. And as you
> noted, it's an instruction set. Very hard if not impossible to parse in
> order to get back the original semantics.
>
I think in this discussion "p4-ish" devices means devices with multiple
tables in a pipeline? Not devices that have programmable/configurable
pipelines right? And if we get to talking about reconfigurable devices
I believe this should be done out of band as it typically means
reloading some ucode, etc.
.John
^ permalink raw reply
* [PATCH net-next] sctp: clean up sctp_packet_transmit
From: Xin Long @ 2016-10-31 16:49 UTC (permalink / raw)
To: network dev, linux-sctp
Cc: Marcelo Ricardo Leitner, Neil Horman, Vlad Yasevich, davem
After adding sctp gso, sctp_packet_transmit is a quite big function now.
This patch is to extract the codes for packing packet to sctp_packet_pack
from sctp_packet_transmit, and add some comments, simplify the err path by
freeing auth chunk when freeing packet chunk_list in out path and freeing
head skb early if it fails to pack packet.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
net/sctp/output.c | 435 ++++++++++++++++++++----------------------------------
1 file changed, 158 insertions(+), 277 deletions(-)
diff --git a/net/sctp/output.c b/net/sctp/output.c
index 7b50e43..f5320a8 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -399,187 +399,72 @@ static void sctp_packet_set_owner_w(struct sk_buff *skb, struct sock *sk)
atomic_inc(&sk->sk_wmem_alloc);
}
-/* All packets are sent to the network through this function from
- * sctp_outq_tail().
- *
- * The return value is a normal kernel error return value.
- */
-int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp)
+static int sctp_packet_pack(struct sctp_packet *packet,
+ struct sk_buff *head, int gso, gfp_t gfp)
{
struct sctp_transport *tp = packet->transport;
- struct sctp_association *asoc = tp->asoc;
- struct sctphdr *sh;
- struct sk_buff *nskb = NULL, *head = NULL;
+ struct sctp_auth_chunk *auth = NULL;
struct sctp_chunk *chunk, *tmp;
- struct sock *sk;
- int err = 0;
- int padding; /* How much padding do we need? */
- int pkt_size;
- __u8 has_data = 0;
- int gso = 0;
- int pktcount = 0;
+ int pkt_count = 0, pkt_size;
+ struct sock *sk = head->sk;
+ struct sk_buff *nskb;
int auth_len = 0;
- struct dst_entry *dst;
- unsigned char *auth = NULL; /* pointer to auth in skb data */
-
- pr_debug("%s: packet:%p\n", __func__, packet);
- /* Do NOT generate a chunkless packet. */
- if (list_empty(&packet->chunk_list))
- return err;
-
- /* Set up convenience variables... */
- chunk = list_entry(packet->chunk_list.next, struct sctp_chunk, list);
- sk = chunk->skb->sk;
-
- /* Allocate the head skb, or main one if not in GSO */
- if (packet->size > tp->pathmtu && !packet->ipfragok) {
- if (sk_can_gso(sk)) {
- gso = 1;
- pkt_size = packet->overhead;
- } else {
- /* If this happens, we trash this packet and try
- * to build a new one, hopefully correct this
- * time. Application may notice this error.
- */
- pr_err_once("Trying to GSO but underlying device doesn't support it.");
- goto err;
- }
- } else {
- pkt_size = packet->size;
- }
- head = alloc_skb(pkt_size + MAX_HEADER, gfp);
- if (!head)
- goto err;
if (gso) {
- NAPI_GRO_CB(head)->last = head;
skb_shinfo(head)->gso_type = sk->sk_gso_type;
+ NAPI_GRO_CB(head)->last = head;
+ } else {
+ nskb = head;
+ pkt_size = packet->size;
+ goto merge;
}
- /* Make sure the outbound skb has enough header room reserved. */
- skb_reserve(head, packet->overhead + MAX_HEADER);
-
- /* Set the owning socket so that we know where to get the
- * destination IP address.
- */
- sctp_packet_set_owner_w(head, sk);
-
- if (!sctp_transport_dst_check(tp)) {
- sctp_transport_route(tp, NULL, sctp_sk(sk));
- if (asoc && (asoc->param_flags & SPP_PMTUD_ENABLE)) {
- sctp_assoc_sync_pmtu(sk, asoc);
- }
- }
- dst = dst_clone(tp->dst);
- if (!dst) {
- if (asoc)
- IP_INC_STATS(sock_net(asoc->base.sk),
- IPSTATS_MIB_OUTNOROUTES);
- goto nodst;
- }
- skb_dst_set(head, dst);
-
- /* Build the SCTP header. */
- sh = (struct sctphdr *)skb_push(head, sizeof(struct sctphdr));
- skb_reset_transport_header(head);
- sh->source = htons(packet->source_port);
- sh->dest = htons(packet->destination_port);
-
- /* From 6.8 Adler-32 Checksum Calculation:
- * After the packet is constructed (containing the SCTP common
- * header and one or more control or DATA chunks), the
- * transmitter shall:
- *
- * 1) Fill in the proper Verification Tag in the SCTP common
- * header and initialize the checksum field to 0's.
- */
- sh->vtag = htonl(packet->vtag);
- sh->checksum = 0;
-
- pr_debug("***sctp_transmit_packet***\n");
-
do {
- /* Set up convenience variables... */
- chunk = list_entry(packet->chunk_list.next, struct sctp_chunk, list);
- pktcount++;
-
- /* Calculate packet size, so it fits in PMTU. Leave
- * other chunks for the next packets.
- */
- if (gso) {
- pkt_size = packet->overhead;
- list_for_each_entry(chunk, &packet->chunk_list, list) {
- int padded = SCTP_PAD4(chunk->skb->len);
-
- if (chunk == packet->auth)
- auth_len = padded;
- else if (auth_len + padded + packet->overhead >
- tp->pathmtu)
- goto nomem;
- else if (pkt_size + padded > tp->pathmtu)
- break;
- pkt_size += padded;
- }
-
- /* Allocate a new skb. */
- nskb = alloc_skb(pkt_size + MAX_HEADER, gfp);
- if (!nskb)
- goto nomem;
+ /* calculate the pkt_size and alloc nskb */
+ pkt_size = packet->overhead;
+ list_for_each_entry_safe(chunk, tmp, &packet->chunk_list,
+ list) {
+ int padded = SCTP_PAD4(chunk->skb->len);
- /* Make sure the outbound skb has enough header
- * room reserved.
- */
- skb_reserve(nskb, packet->overhead + MAX_HEADER);
- } else {
- nskb = head;
+ if (chunk == packet->auth)
+ auth_len = padded;
+ else if (auth_len + padded + packet->overhead >
+ tp->pathmtu)
+ return 0;
+ else if (pkt_size + padded > tp->pathmtu)
+ break;
+ pkt_size += padded;
}
+ nskb = alloc_skb(pkt_size + MAX_HEADER, gfp);
+ if (!nskb)
+ return 0;
+ skb_reserve(nskb, packet->overhead + MAX_HEADER);
- /**
- * 3.2 Chunk Field Descriptions
- *
- * The total length of a chunk (including Type, Length and
- * Value fields) MUST be a multiple of 4 bytes. If the length
- * of the chunk is not a multiple of 4 bytes, the sender MUST
- * pad the chunk with all zero bytes and this padding is not
- * included in the chunk length field. The sender should
- * never pad with more than 3 bytes.
- *
- * [This whole comment explains SCTP_PAD4() below.]
- */
-
+merge:
+ /* merge chunks into nskb and append nskb into head list */
pkt_size -= packet->overhead;
list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) {
+ int padding;
+
list_del_init(&chunk->list);
if (sctp_chunk_is_data(chunk)) {
- /* 6.3.1 C4) When data is in flight and when allowed
- * by rule C5, a new RTT measurement MUST be made each
- * round trip. Furthermore, new RTT measurements
- * SHOULD be made no more than once per round-trip
- * for a given destination transport address.
- */
-
if (!sctp_chunk_retransmitted(chunk) &&
!tp->rto_pending) {
chunk->rtt_in_progress = 1;
tp->rto_pending = 1;
}
-
- has_data = 1;
}
padding = SCTP_PAD4(chunk->skb->len) - chunk->skb->len;
if (padding)
memset(skb_put(chunk->skb, padding), 0, padding);
- /* if this is the auth chunk that we are adding,
- * store pointer where it will be added and put
- * the auth into the packet.
- */
if (chunk == packet->auth)
- auth = skb_tail_pointer(nskb);
+ auth = (struct sctp_auth_chunk *)
+ skb_tail_pointer(nskb);
- memcpy(skb_put(nskb, chunk->skb->len),
- chunk->skb->data, chunk->skb->len);
+ memcpy(skb_put(nskb, chunk->skb->len), chunk->skb->data,
+ chunk->skb->len);
pr_debug("*** Chunk:%p[%s] %s 0x%x, length:%d, chunk->skb->len:%d, rtt_in_progress:%d\n",
chunk,
@@ -589,11 +474,6 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp)
ntohs(chunk->chunk_hdr->length), chunk->skb->len,
chunk->rtt_in_progress);
- /* If this is a control chunk, this is our last
- * reference. Free data chunks after they've been
- * acknowledged or have failed.
- * Re-queue auth chunks if needed.
- */
pkt_size -= SCTP_PAD4(chunk->skb->len);
if (!sctp_chunk_is_data(chunk) && chunk != packet->auth)
@@ -603,160 +483,161 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp)
break;
}
- /* SCTP-AUTH, Section 6.2
- * The sender MUST calculate the MAC as described in RFC2104 [2]
- * using the hash function H as described by the MAC Identifier and
- * the shared association key K based on the endpoint pair shared key
- * described by the shared key identifier. The 'data' used for the
- * computation of the AUTH-chunk is given by the AUTH chunk with its
- * HMAC field set to zero (as shown in Figure 6) followed by all
- * chunks that are placed after the AUTH chunk in the SCTP packet.
- */
- if (auth)
- sctp_auth_calculate_hmac(asoc, nskb,
- (struct sctp_auth_chunk *)auth,
- gfp);
-
- if (packet->auth) {
- if (!list_empty(&packet->chunk_list)) {
- /* We will generate more packets, so re-queue
- * auth chunk.
- */
+ if (auth) {
+ sctp_auth_calculate_hmac(tp->asoc, nskb, auth, gfp);
+ /* free auth if no more chunks, or add it back */
+ if (list_empty(&packet->chunk_list))
+ sctp_chunk_free(packet->auth);
+ else
list_add(&packet->auth->list,
&packet->chunk_list);
- } else {
- sctp_chunk_free(packet->auth);
- packet->auth = NULL;
- }
}
- if (!gso)
- break;
-
- if (skb_gro_receive(&head, nskb)) {
- kfree_skb(nskb);
- goto nomem;
+ if (gso) {
+ if (skb_gro_receive(&head, nskb)) {
+ kfree_skb(nskb);
+ return 0;
+ }
+ if (WARN_ON_ONCE(skb_shinfo(head)->gso_segs >=
+ sk->sk_gso_max_segs))
+ return 0;
}
- nskb = NULL;
- if (WARN_ON_ONCE(skb_shinfo(head)->gso_segs >=
- sk->sk_gso_max_segs))
- goto nomem;
+
+ pkt_count++;
} while (!list_empty(&packet->chunk_list));
- /* 2) Calculate the Adler-32 checksum of the whole packet,
- * including the SCTP common header and all the
- * chunks.
- *
- * Note: Adler-32 is no longer applicable, as has been replaced
- * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>.
- *
- * If it's a GSO packet, it's postponed to sctp_skb_segment.
- */
- if (!sctp_checksum_disable || gso) {
- if (!gso && (!(dst->dev->features & NETIF_F_SCTP_CRC) ||
- dst_xfrm(dst) || packet->ipfragok)) {
- sh->checksum = sctp_compute_cksum(head, 0);
- } else {
- /* no need to seed pseudo checksum for SCTP */
- head->ip_summed = CHECKSUM_PARTIAL;
- head->csum_start = skb_transport_header(head) - head->head;
- head->csum_offset = offsetof(struct sctphdr, checksum);
+ if (gso) {
+ memset(head->cb, 0, max(sizeof(struct inet_skb_parm),
+ sizeof(struct inet6_skb_parm)));
+ skb_shinfo(head)->gso_segs = pkt_count;
+ skb_shinfo(head)->gso_size = GSO_BY_FRAGS;
+ rcu_read_lock();
+ if (skb_dst(head) != tp->dst) {
+ dst_hold(tp->dst);
+ sk_setup_caps(sk, tp->dst);
}
+ rcu_read_unlock();
+ goto chksum;
}
- /* IP layer ECN support
- * From RFC 2481
- * "The ECN-Capable Transport (ECT) bit would be set by the
- * data sender to indicate that the end-points of the
- * transport protocol are ECN-capable."
- *
- * Now setting the ECT bit all the time, as it should not cause
- * any problems protocol-wise even if our peer ignores it.
- *
- * Note: The works for IPv6 layer checks this bit too later
- * in transmission. See IP6_ECN_flow_xmit().
- */
- tp->af_specific->ecn_capable(sk);
+ if (sctp_checksum_disable)
+ return 1;
- /* Set up the IP options. */
- /* BUG: not implemented
- * For v4 this all lives somewhere in sk->sk_opt...
- */
+ if (!(skb_dst(head)->dev->features & NETIF_F_SCTP_CRC) ||
+ dst_xfrm(skb_dst(head)) || packet->ipfragok) {
+ struct sctphdr *sh =
+ (struct sctphdr *)skb_transport_header(head);
- /* Dump that on IP! */
- if (asoc) {
- asoc->stats.opackets += pktcount;
- if (asoc->peer.last_sent_to != tp)
- /* Considering the multiple CPU scenario, this is a
- * "correcter" place for last_sent_to. --xguo
- */
- asoc->peer.last_sent_to = tp;
+ sh->checksum = sctp_compute_cksum(head, 0);
+ } else {
+chksum:
+ head->ip_summed = CHECKSUM_PARTIAL;
+ head->csum_start = skb_transport_header(head) - head->head;
+ head->csum_offset = offsetof(struct sctphdr, checksum);
}
- if (has_data) {
- struct timer_list *timer;
- unsigned long timeout;
+ return pkt_count;
+}
+
+/* All packets are sent to the network through this function from
+ * sctp_outq_tail().
+ *
+ * The return value is always 0 for now.
+ */
+int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp)
+{
+ struct sctp_transport *tp = packet->transport;
+ struct sctp_association *asoc = tp->asoc;
+ struct sctp_chunk *chunk, *tmp;
+ int pkt_count, gso = 0;
+ struct dst_entry *dst;
+ struct sk_buff *head;
+ struct sctphdr *sh;
+ struct sock *sk;
- /* Restart the AUTOCLOSE timer when sending data. */
- if (sctp_state(asoc, ESTABLISHED) &&
- asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) {
- timer = &asoc->timers[SCTP_EVENT_TIMEOUT_AUTOCLOSE];
- timeout = asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE];
+ pr_debug("%s: packet:%p\n", __func__, packet);
+ if (list_empty(&packet->chunk_list))
+ return 0;
+ chunk = list_entry(packet->chunk_list.next, struct sctp_chunk, list);
+ sk = chunk->skb->sk;
- if (!mod_timer(timer, jiffies + timeout))
- sctp_association_hold(asoc);
+ /* check gso */
+ if (packet->size > tp->pathmtu && !packet->ipfragok) {
+ if (!sk_can_gso(sk)) {
+ pr_err_once("Trying to GSO but underlying device doesn't support it.");
+ goto out;
}
+ gso = 1;
+ }
+
+ /* alloc head skb */
+ head = alloc_skb((gso ? packet->overhead : packet->size) +
+ MAX_HEADER, gfp);
+ if (!head)
+ goto out;
+ skb_reserve(head, packet->overhead + MAX_HEADER);
+ sctp_packet_set_owner_w(head, sk);
+
+ /* set sctp header */
+ sh = (struct sctphdr *)skb_push(head, sizeof(struct sctphdr));
+ skb_reset_transport_header(head);
+ sh->source = htons(packet->source_port);
+ sh->dest = htons(packet->destination_port);
+ sh->vtag = htonl(packet->vtag);
+ sh->checksum = 0;
+
+ /* update dst if in need */
+ if (!sctp_transport_dst_check(tp)) {
+ sctp_transport_route(tp, NULL, sctp_sk(sk));
+ if (asoc && asoc->param_flags & SPP_PMTUD_ENABLE)
+ sctp_assoc_sync_pmtu(sk, asoc);
}
+ dst = dst_clone(tp->dst);
+ if (!dst) {
+ IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
+ kfree_skb(head);
+ goto out;
+ }
+ skb_dst_set(head, dst);
+ /* pack up chunks */
+ pkt_count = sctp_packet_pack(packet, head, gso, gfp);
+ if (!pkt_count) {
+ kfree_skb(head);
+ goto out;
+ }
pr_debug("***sctp_transmit_packet*** skb->len:%d\n", head->len);
- if (gso) {
- /* Cleanup our debris for IP stacks */
- memset(head->cb, 0, max(sizeof(struct inet_skb_parm),
- sizeof(struct inet6_skb_parm)));
+ /* start autoclose timer */
+ if (packet->has_data && sctp_state(asoc, ESTABLISHED) &&
+ asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) {
+ struct timer_list *timer =
+ &asoc->timers[SCTP_EVENT_TIMEOUT_AUTOCLOSE];
+ unsigned long timeout =
+ asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE];
- skb_shinfo(head)->gso_segs = pktcount;
- skb_shinfo(head)->gso_size = GSO_BY_FRAGS;
+ if (!mod_timer(timer, jiffies + timeout))
+ sctp_association_hold(asoc);
+ }
- /* We have to refresh this in case we are xmiting to
- * more than one transport at a time
- */
- rcu_read_lock();
- if (__sk_dst_get(sk) != tp->dst) {
- dst_hold(tp->dst);
- sk_setup_caps(sk, tp->dst);
- }
- rcu_read_unlock();
+ /* sctp xmit */
+ tp->af_specific->ecn_capable(sk);
+ if (asoc) {
+ asoc->stats.opackets += pkt_count;
+ if (asoc->peer.last_sent_to != tp)
+ asoc->peer.last_sent_to = tp;
}
head->ignore_df = packet->ipfragok;
tp->af_specific->sctp_xmit(head, tp);
- goto out;
-
-nomem:
- if (packet->auth && list_empty(&packet->auth->list))
- sctp_chunk_free(packet->auth);
-
-nodst:
- /* FIXME: Returning the 'err' will effect all the associations
- * associated with a socket, although only one of the paths of the
- * association is unreachable.
- * The real failure of a transport or association can be passed on
- * to the user via notifications. So setting this error may not be
- * required.
- */
- /* err = -EHOSTUNREACH; */
- kfree_skb(head);
-err:
+out:
list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) {
list_del_init(&chunk->list);
if (!sctp_chunk_is_data(chunk))
sctp_chunk_free(chunk);
}
-
-out:
sctp_packet_reset(packet);
- return err;
+ return 0;
}
/********************************************************************
--
2.1.0
^ permalink raw reply related
* [PATCH 07/12] xen: make use of xenbus_read_unsigned() in xen-netfront
From: Juergen Gross @ 2016-10-31 16:48 UTC (permalink / raw)
To: linux-kernel, xen-devel
Cc: david.vrabel, boris.ostrovsky, Juergen Gross, netdev
In-Reply-To: <1477932510-28594-1-git-send-email-jgross@suse.com>
Use xenbus_read_unsigned() instead of xenbus_scanf() when possible.
This requires to change the type of some reads from int to unsigned,
but these cases have been wrong before: negative values are not allowed
for the modified cases.
Cc: netdev@vger.kernel.org
Signed-off-by: Juergen Gross <jgross@suse.com>
---
drivers/net/xen-netfront.c | 67 +++++++++++++---------------------------------
1 file changed, 18 insertions(+), 49 deletions(-)
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index e17879d..95d664e 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1169,43 +1169,23 @@ static netdev_features_t xennet_fix_features(struct net_device *dev,
netdev_features_t features)
{
struct netfront_info *np = netdev_priv(dev);
- int val;
- if (features & NETIF_F_SG) {
- if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, "feature-sg",
- "%d", &val) < 0)
- val = 0;
+ if (features & NETIF_F_SG &&
+ !xenbus_read_unsigned(np->xbdev->otherend, "feature-sg", 0))
+ features &= ~NETIF_F_SG;
- if (!val)
- features &= ~NETIF_F_SG;
- }
+ if (features & NETIF_F_IPV6_CSUM &&
+ !xenbus_read_unsigned(np->xbdev->otherend,
+ "feature-ipv6-csum-offload", 0))
+ features &= ~NETIF_F_IPV6_CSUM;
- if (features & NETIF_F_IPV6_CSUM) {
- if (xenbus_scanf(XBT_NIL, np->xbdev->otherend,
- "feature-ipv6-csum-offload", "%d", &val) < 0)
- val = 0;
+ if (features & NETIF_F_TSO &&
+ !xenbus_read_unsigned(np->xbdev->otherend, "feature-gso-tcpv4", 0))
+ features &= ~NETIF_F_TSO;
- if (!val)
- features &= ~NETIF_F_IPV6_CSUM;
- }
-
- if (features & NETIF_F_TSO) {
- if (xenbus_scanf(XBT_NIL, np->xbdev->otherend,
- "feature-gso-tcpv4", "%d", &val) < 0)
- val = 0;
-
- if (!val)
- features &= ~NETIF_F_TSO;
- }
-
- if (features & NETIF_F_TSO6) {
- if (xenbus_scanf(XBT_NIL, np->xbdev->otherend,
- "feature-gso-tcpv6", "%d", &val) < 0)
- val = 0;
-
- if (!val)
- features &= ~NETIF_F_TSO6;
- }
+ if (features & NETIF_F_TSO6 &&
+ !xenbus_read_unsigned(np->xbdev->otherend, "feature-gso-tcpv6", 0))
+ features &= ~NETIF_F_TSO6;
return features;
}
@@ -1821,18 +1801,13 @@ static int talk_to_netback(struct xenbus_device *dev,
info->netdev->irq = 0;
/* Check if backend supports multiple queues */
- err = xenbus_scanf(XBT_NIL, info->xbdev->otherend,
- "multi-queue-max-queues", "%u", &max_queues);
- if (err < 0)
- max_queues = 1;
+ max_queues = xenbus_read_unsigned(info->xbdev->otherend,
+ "multi-queue-max-queues", 1);
num_queues = min(max_queues, xennet_max_queues);
/* Check feature-split-event-channels */
- err = xenbus_scanf(XBT_NIL, info->xbdev->otherend,
- "feature-split-event-channels", "%u",
- &feature_split_evtchn);
- if (err < 0)
- feature_split_evtchn = 0;
+ feature_split_evtchn = xenbus_read_unsigned(info->xbdev->otherend,
+ "feature-split-event-channels", 0);
/* Read mac addr. */
err = xen_net_read_mac(dev, info->netdev->dev_addr);
@@ -1966,16 +1941,10 @@ static int xennet_connect(struct net_device *dev)
struct netfront_info *np = netdev_priv(dev);
unsigned int num_queues = 0;
int err;
- unsigned int feature_rx_copy;
unsigned int j = 0;
struct netfront_queue *queue = NULL;
- err = xenbus_scanf(XBT_NIL, np->xbdev->otherend,
- "feature-rx-copy", "%u", &feature_rx_copy);
- if (err != 1)
- feature_rx_copy = 0;
-
- if (!feature_rx_copy) {
+ if (!xenbus_read_unsigned(np->xbdev->otherend, "feature-rx-copy", 0)) {
dev_info(&dev->dev,
"backend does not support copying receive path\n");
return -ENODEV;
--
2.6.6
^ permalink raw reply related
* [PATCH 06/12] xen: make use of xenbus_read_unsigned() in xen-netback
From: Juergen Gross @ 2016-10-31 16:48 UTC (permalink / raw)
To: linux-kernel, xen-devel
Cc: david.vrabel, boris.ostrovsky, Juergen Gross, wei.liu2,
paul.durrant, netdev
In-Reply-To: <1477932510-28594-1-git-send-email-jgross@suse.com>
Use xenbus_read_unsigned() instead of xenbus_scanf() when possible.
This requires to change the type of some reads from int to unsigned,
but these cases have been wrong before: negative values are not allowed
for the modified cases.
Cc: wei.liu2@citrix.com
Cc: paul.durrant@citrix.com
Cc: netdev@vger.kernel.org
Signed-off-by: Juergen Gross <jgross@suse.com>
---
drivers/net/xen-netback/xenbus.c | 50 +++++++++++-----------------------------
1 file changed, 14 insertions(+), 36 deletions(-)
diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c
index 8674e18..7356e00 100644
--- a/drivers/net/xen-netback/xenbus.c
+++ b/drivers/net/xen-netback/xenbus.c
@@ -785,12 +785,9 @@ static void xen_mcast_ctrl_changed(struct xenbus_watch *watch,
struct xenvif *vif = container_of(watch, struct xenvif,
mcast_ctrl_watch);
struct xenbus_device *dev = xenvif_to_xenbus_device(vif);
- int val;
- if (xenbus_scanf(XBT_NIL, dev->otherend,
- "request-multicast-control", "%d", &val) < 0)
- val = 0;
- vif->multicast_control = !!val;
+ vif->multicast_control = !!xenbus_read_unsigned(dev->otherend,
+ "request-multicast-control", 0);
}
static int xen_register_mcast_ctrl_watch(struct xenbus_device *dev,
@@ -934,12 +931,9 @@ static void connect(struct backend_info *be)
/* Check whether the frontend requested multiple queues
* and read the number requested.
*/
- err = xenbus_scanf(XBT_NIL, dev->otherend,
- "multi-queue-num-queues",
- "%u", &requested_num_queues);
- if (err < 0) {
- requested_num_queues = 1; /* Fall back to single queue */
- } else if (requested_num_queues > xenvif_max_queues) {
+ requested_num_queues = xenbus_read_unsigned(dev->otherend,
+ "multi-queue-num-queues", 1);
+ if (requested_num_queues > xenvif_max_queues) {
/* buggy or malicious guest */
xenbus_dev_fatal(dev, err,
"guest requested %u queues, exceeding the maximum of %u.",
@@ -1134,7 +1128,7 @@ static int read_xenbus_vif_flags(struct backend_info *be)
struct xenvif *vif = be->vif;
struct xenbus_device *dev = be->dev;
unsigned int rx_copy;
- int err, val;
+ int err;
err = xenbus_scanf(XBT_NIL, dev->otherend, "request-rx-copy", "%u",
&rx_copy);
@@ -1150,10 +1144,7 @@ static int read_xenbus_vif_flags(struct backend_info *be)
if (!rx_copy)
return -EOPNOTSUPP;
- if (xenbus_scanf(XBT_NIL, dev->otherend,
- "feature-rx-notify", "%d", &val) < 0)
- val = 0;
- if (!val) {
+ if (!xenbus_read_unsigned(dev->otherend, "feature-rx-notify", 0)) {
/* - Reduce drain timeout to poll more frequently for
* Rx requests.
* - Disable Rx stall detection.
@@ -1162,34 +1153,21 @@ static int read_xenbus_vif_flags(struct backend_info *be)
be->vif->stall_timeout = 0;
}
- if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-sg",
- "%d", &val) < 0)
- val = 0;
- vif->can_sg = !!val;
+ vif->can_sg = !!xenbus_read_unsigned(dev->otherend, "feature-sg", 0);
vif->gso_mask = 0;
- if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-gso-tcpv4",
- "%d", &val) < 0)
- val = 0;
- if (val)
+ if (xenbus_read_unsigned(dev->otherend, "feature-gso-tcpv4", 0))
vif->gso_mask |= GSO_BIT(TCPV4);
- if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-gso-tcpv6",
- "%d", &val) < 0)
- val = 0;
- if (val)
+ if (xenbus_read_unsigned(dev->otherend, "feature-gso-tcpv6", 0))
vif->gso_mask |= GSO_BIT(TCPV6);
- if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-no-csum-offload",
- "%d", &val) < 0)
- val = 0;
- vif->ip_csum = !val;
+ vif->ip_csum = !xenbus_read_unsigned(dev->otherend,
+ "feature-no-csum-offload", 0);
- if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-ipv6-csum-offload",
- "%d", &val) < 0)
- val = 0;
- vif->ipv6_csum = !!val;
+ vif->ipv6_csum = !!xenbus_read_unsigned(dev->otherend,
+ "feature-ipv6-csum-offload", 0);
return 0;
}
--
2.6.6
^ permalink raw reply related
* [PATCH 00/12] xen: add common function for reading optional value
From: Juergen Gross @ 2016-10-31 16:48 UTC (permalink / raw)
To: linux-kernel, xen-devel
Cc: david.vrabel, boris.ostrovsky, Juergen Gross, konrad.wilk,
roger.pau, peterhuewe, tpmdd, jarkko.sakkinen, jgunthorpe,
tpmdd-devel, dmitry.torokhov, linux-input, wei.liu2, paul.durrant,
netdev, bhelgaas, linux-pci, tomi.valkeinen, linux-fbdev
There are multiple instances of code reading an optional unsigned
parameter from Xenstore via xenbus_scanf(). Instead of repeating the
same code over and over add a service function doing the job and
replace the call of xenbus_scanf() with the call of the new function
where appropriate.
Juergen Gross (12):
xen: introduce xenbus_read_unsigned()
xen: make use of xenbus_read_unsigned() in xen-blkback
xen: make use of xenbus_read_unsigned() in xen-blkfront
xen: make use of xenbus_read_unsigned() in xen-tpmfront
xen: make use of xenbus_read_unsigned() in xen-kbdfront
xen: make use of xenbus_read_unsigned() in xen-netback
xen: make use of xenbus_read_unsigned() in xen-netfront
xen: make use of xenbus_read_unsigned() in xen-pcifront
xen: make use of xenbus_read_unsigned() in xen-scsifront
xen: make use of xenbus_read_unsigned() in xen-fbfront
xen: make use of xenbus_read_unsigned() in xen-pciback
xen: make use of xenbus_read_unsigned() in xenbus
drivers/block/xen-blkback/xenbus.c | 36 ++++++--------
drivers/block/xen-blkfront.c | 81 ++++++++++---------------------
drivers/char/tpm/xen-tpmfront.c | 8 +--
drivers/input/misc/xen-kbdfront.c | 13 ++---
drivers/net/xen-netback/xenbus.c | 50 ++++++-------------
drivers/net/xen-netfront.c | 67 +++++++------------------
drivers/pci/xen-pcifront.c | 6 +--
drivers/scsi/xen-scsifront.c | 6 +--
drivers/video/fbdev/xen-fbfront.c | 13 ++---
drivers/xen/xen-pciback/xenbus.c | 8 ++-
drivers/xen/xenbus/xenbus_probe_backend.c | 8 +--
drivers/xen/xenbus/xenbus_xs.c | 22 +++++++--
include/xen/xenbus.h | 4 ++
13 files changed, 112 insertions(+), 210 deletions(-)
Cc: konrad.wilk@oracle.com
Cc: roger.pau@citrix.com
Cc: peterhuewe@gmx.de
Cc: tpmdd@selhorst.net
Cc: jarkko.sakkinen@linux.intel.com
Cc: jgunthorpe@obsidianresearch.com
Cc: tpmdd-devel@lists.sourceforge.net
Cc: dmitry.torokhov@gmail.com
Cc: linux-input@vger.kernel.org
Cc: wei.liu2@citrix.com
Cc: paul.durrant@citrix.com
Cc: netdev@vger.kernel.org
Cc: bhelgaas@google.com
Cc: linux-pci@vger.kernel.org
Cc: tomi.valkeinen@ti.com
Cc: linux-fbdev@vger.kernel.org
--
2.6.6
^ permalink raw reply
* Re: [PATCH v7 5/6] net: ipv4, ipv6: run cgroup eBPF egress programs
From: David Miller @ 2016-10-31 16:40 UTC (permalink / raw)
To: daniel
Cc: htejun, daniel, ast, kafai, fw, pablo, harald, netdev, sargun,
cgroups
In-Reply-To: <1477390454-12553-6-git-send-email-daniel@zonque.org>
From: Daniel Mack <daniel@zonque.org>
Date: Tue, 25 Oct 2016 12:14:13 +0200
> @@ -312,6 +314,13 @@ int ip_mc_output(struct net *net, struct sock *sk, struct sk_buff *skb)
> skb->dev = dev;
> skb->protocol = htons(ETH_P_IP);
>
> + ret = cgroup_bpf_run_filter(sk_to_full_sk(sk), skb,
> + BPF_CGROUP_INET_EGRESS);
> + if (ret) {
> + kfree_skb(skb);
> + return ret;
> + }
> +
> /*
> * Multicasts are looped back for other local users
> */
> @@ -364,12 +373,20 @@ int ip_mc_output(struct net *net, struct sock *sk, struct sk_buff *skb)
> int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb)
> {
> struct net_device *dev = skb_dst(skb)->dev;
> + int ret;
>
> IP_UPD_PO_STATS(net, IPSTATS_MIB_OUT, skb->len);
>
> skb->dev = dev;
> skb->protocol = htons(ETH_P_IP);
>
> + ret = cgroup_bpf_run_filter(sk_to_full_sk(sk), skb,
> + BPF_CGROUP_INET_EGRESS);
> + if (ret) {
> + kfree_skb(skb);
> + return ret;
> + }
> +
> return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING,
> net, sk, skb, NULL, dev,
> ip_finish_output,
The "sk" here is not necessarily the application socket. It could be
a UDP tunnel socket or similar encapsulation object.
"skb->sk" is always the application socket, so is probably what you
need to pass down into the cgroup bpf run filter hook.
^ permalink raw reply
* Re: Ethernet not working on a different SoC with same eth HW
From: Mason @ 2016-10-31 16:28 UTC (permalink / raw)
To: Andrew Lunn
Cc: netdev, Mans Rullgard, Florian Fainelli, Timur Tabi,
Sergei Shtylyov, Zefir Kurtisi, Martin Blumenstingl,
Uwe Kleine-Konig, Daniel Mack, Sebastian Frias
In-Reply-To: <20161031155334.GF9441@lunn.ch>
On 31/10/2016 16:53, Andrew Lunn wrote:
>> I'll add a log for the request_irq call.
>
> And take a look at /proc/interrupts
You're right, there does seem to be something wrong with the interrupts.
# cat /proc/interrupts
CPU0
20: 26285 GIC-0 29 Edge twd
IPI0: 0 CPU wakeup interrupts
IPI1: 0 Timer broadcast interrupts
IPI2: 0 Rescheduling interrupts
IPI3: 0 Function call interrupts
IPI4: 0 CPU stop interrupts
IPI5: 0 IRQ work interrupts
IPI6: 0 completion interrupts
Err: 0
None of the expected platform interrupts (eth, phy, uart) are registered.
Thanks for pushing in a promising direction.
Regards.
^ permalink raw reply
* Re: [PATCH net-next 3/4] bpf: BPF for lightweight tunnel encapsulation
From: Tom Herbert @ 2016-10-31 16:07 UTC (permalink / raw)
To: Thomas Graf
Cc: David S. Miller, Alexei Starovoitov, Daniel Borkmann,
Linux Kernel Network Developers, roopa
In-Reply-To: <20161031150640.GC32374@pox.localdomain>
On Mon, Oct 31, 2016 at 8:06 AM, Thomas Graf <tgraf@suug.ch> wrote:
> On 10/31/16 at 07:17am, Tom Herbert wrote:
>> On Mon, Oct 31, 2016 at 5:59 AM, Thomas Graf <tgraf@suug.ch> wrote:
>> > Noticed while implementing this: How does ILA ensure that dst_output()
>> > is not invoked in a circular manner?
>> >
>> > dstA->output() -> dstB->otuput() -> dstA->output() -> ...
>>
>> It doesn't. We'll need to add a check for that. Maybe the rule should
>> be that an skbuff is only allowed to hit one LWT route?
>
> I'll add a per cpu variable to do a recursion limit for dst_output()
> which callers to possibly recurse can use. ILA can use that as well.
>
>> Another scenario to consider: Suppose someone is doing protocol
>> translation like in RFC7915. This is one of operations we'd need with
>> ILA or GRE to implement an IPv4 overlay network over IPv6. Would this
>> be allowed/supported in LWT BPF?
>
> In lwtunnel_xmit() yes, input and output would not support this right
> now. It will need some logic as the orig_input and orig_output would
> obviously be expecting the same protocol. This is the reason why the
> xmit prog type currently has a wider set of allowed helpers.
I guess this leads to a more general question I have about the effects
of allowing userspace to insert code in the kernel that modifies
packets. If we allow BPF programs to arbitrarily modify packets in
LWT, how do we ensure that there are no insidious effects later in the
path? For instance, what someone uses BPF to convert an IPv6 packet
to IPv4, or maybe convert packet to something that isn't even IP, or
what if someone just decides to overwrite every byte in a packet with
0xff? Are these thing allowed, and if so what is the effect? I would
assume a policy that these can't cause any insidious effects to
unrelated traffic or the rest of the system, in particular such things
should not cause the kernel to crash (based on the principle that
user space code should never cause kernel to crash). I think XDP might
be okay since the path is straightforward and only deals with raw
packets, but LWT is much higher in that stack.
Thanks,
Tom
^ permalink raw reply
* Re: Ethernet not working on a different SoC with same eth HW
From: Andrew Lunn @ 2016-10-31 15:53 UTC (permalink / raw)
To: Mason
Cc: netdev, Mans Rullgard, Florian Fainelli, Timur Tabi,
Sergei Shtylyov, Zefir Kurtisi, Martin Blumenstingl,
Uwe Kleine-Konig, Daniel Mack, Sebastian Frias
In-Reply-To: <581767BF.4020308@free.fr>
> I'll add a log for the request_irq call.
And take a look at /proc/interrupts
Andrew
^ permalink raw reply
* (unknown),
From: Debra_Farmer/SSB/HIDOE @ 2016-10-31 13:59 UTC (permalink / raw)
I am Mrs. Gu Kailai and i intend to make a DONATION. Contact my personal E-mail Via: mrsgukailai@post.cz for more details:
^ permalink raw reply
* Re: Ethernet not working on a different SoC with same eth HW
From: Mason @ 2016-10-31 15:48 UTC (permalink / raw)
To: Andrew Lunn
Cc: netdev, Mans Rullgard, Florian Fainelli, Timur Tabi,
Sergei Shtylyov, Zefir Kurtisi, Martin Blumenstingl,
Uwe Kleine-Konig, Daniel Mack, Sebastian Frias
In-Reply-To: <20161031153704.GD9441@lunn.ch>
On 31/10/2016 16:37, Andrew Lunn wrote:
>> The regnum=5,4,1,1,a,9 logs keep repeating, endlessly.
>> Is that expected?
>
> Yes, that is expected, if you are not using interrupts. The phylib
> state machine polls the state of the PHY once per second to see if
> there has been a link up/down.
Interesting. But the logs are showing accesses much more frequent
than once per second, it seems... (?)
And an interrupt for the PHY is configured in the device tree:
ð0 {
#address-cells = <1>;
#size-cells = <0>;
phy-connection-type = "rgmii";
phy-handle = <ð0_phy>;
/* Atheros AR8035 */
eth0_phy: ethernet-phy@4 {
compatible = "ethernet-phy-id004d.d072",
"ethernet-phy-ieee802.3-c22";
interrupts = <37 IRQ_TYPE_EDGE_RISING>;
reg = <4>;
};
};
I'll add a log for the request_irq call.
Regards.
^ permalink raw reply
* Re: Ethernet not working on a different SoC with same eth HW
From: Andrew Lunn @ 2016-10-31 15:39 UTC (permalink / raw)
To: Mason
Cc: netdev, Mans Rullgard, Florian Fainelli, Timur Tabi,
Sergei Shtylyov, Zefir Kurtisi, Martin Blumenstingl,
Uwe Kleine-Konig, Daniel Mack, Sebastian Frias
In-Reply-To: <58176355.7090200@free.fr>
On Mon, Oct 31, 2016 at 04:29:25PM +0100, Mason wrote:
> Hello everyone,
>
> I'm using these net drivers:
>
> drivers/net/ethernet/aurora/nb8800.c
> drivers/net/phy/at803x.c
>
> With a smp8758 board, they work great.
> I've been trying to use them on a different board:
>
> same eth PHY (Atheros AR8035)
> same eth MAC (Aurora SSN8800)
> different SoC (same base address for MAC block)
>
> It doesn't work
Rather vague. What does not work? Please describe the symptoms.
Andrew
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox