* Re: [Bridge] [PATCH net-next v4 2/3] bridge: suppress arp pkts on BR_NEIGH_SUPPRESS ports
From: Toshiaki Makita @ 2017-10-04 7:35 UTC (permalink / raw)
To: Roopa Prabhu, davem; +Cc: nikolay, netdev, bridge
In-Reply-To: <1507093953-59929-3-git-send-email-roopa@cumulusnetworks.com>
On 2017/10/04 14:12, Roopa Prabhu wrote:
> From: Roopa Prabhu <roopa@cumulusnetworks.com>
>
> This patch avoids flooding and proxies arp packets
> for BR_NEIGH_SUPPRESS ports.
>
> Moves existing br_do_proxy_arp to br_do_proxy_suppress_arp
> to support both proxy arp and neigh suppress.
>
> Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
> ---
...
> +static void br_arp_send(struct net_bridge_port *p, int type, int ptype,
type and ptype are always the same so seems unnecessary.
> + __be32 dest_ip, struct net_device *dev,
> + __be32 src_ip, const unsigned char *dest_hw,
> + const unsigned char *src_hw,
> + const unsigned char *target_hw,
> + __be16 vlan_proto, u16 vlan_tci)
> +{
> + struct sk_buff *skb;
> +
> + netdev_dbg(dev, "arp send dev %s dst %pI4 dst_hw %pM src %pI4 src_hw %pM\n",
> + dev->name, &dest_ip, dest_hw, &src_ip, src_hw);
> +
> + if (!vlan_tci) {
> + arp_send(type, ptype, dest_ip, dev, src_ip,
> + dest_hw, src_hw, target_hw);
I may be missing something, but wouldn't it send arp reply from the
bridge device, while it should be received to the bridge device, when p
== NULL?
> + return;
> + }
> +
> + skb = arp_create(type, ptype, dest_ip, dev, src_ip,
> + dest_hw, src_hw, target_hw);
> + if (!skb)
> + return;
> +
> + if (p) {
Why doesn't bridge device consider pvid?
> + struct net_bridge_vlan_group *vg;
> + u16 pvid;
> +
> + vg = nbp_vlan_group_rcu(p);
> + pvid = br_get_pvid(vg);
> + if (pvid == vlan_tci)
Need vlan_tci & VLAN_VID_MASK
Or use skb_vlan_tag_get_id() in caller side.
> + vlan_tci = 0;
> + }
> +
> + if (vlan_tci) {
> + skb = vlan_insert_tag_set_proto(skb, vlan_proto,
> + vlan_tci);
Should be __vlan_hwaccel_put_tag()
> + if (!skb) {
> + net_err_ratelimited("%s: failed to insert VLAN tag\n",
> + __func__);
> + return;
> + }
> + }
> +
> + arp_xmit(skb);
> +}
...
> +void br_do_proxy_suppress_arp(struct sk_buff *skb, struct net_bridge *br,
> + u16 vid, struct net_bridge_port *p)
> +{
...
> + if (br->neigh_suppress_enabled) {
> + if (p && (p->flags & BR_NEIGH_SUPPRESS))
> + return;
> + if (ipv4_is_zeronet(sip) || sip == tip) {
> + /* prevent flooding to neigh suppress ports */
> + BR_INPUT_SKB_CB(skb)->proxyarp_replied = true;
> + return;
> + }
> + }
> +
> + if (parp->ar_op != htons(ARPOP_REQUEST))
> + return;
> +
> + if (vid != 0) {
vid should be 0 if untagged is set on the bridge device?
> + vlandev = __vlan_find_dev_deep_rcu(br->dev, skb->vlan_proto,
> + vid);
> + if (!vlandev)
> + return;
> + }
> +
> + if (br->neigh_suppress_enabled && br_is_local_ip(vlandev, tip)) {
> + /* its our local ip, so don't proxy reply
> + * and don't forward to neigh suppress ports
> + */
> + BR_INPUT_SKB_CB(skb)->proxyarp_replied = true;
> + return;
> + }
--
Toshiaki Makita
^ permalink raw reply
* Re: Fw: [Bug 197099] New: Kernel panic in interrupt [l2tp_ppp]
From: James Chapman @ 2017-10-04 7:49 UTC (permalink / raw)
To: SviMik; +Cc: netdev, Guillaume Nault
In-Reply-To: <CAEwTi7S3-B81bNxyWq8j4hUpXyqNnTADReYoKoGF-V4wC5OBkQ@mail.gmail.com>
On 3 October 2017 at 08:27, James Chapman <jchapman@katalix.com> wrote:
> On 2 October 2017 at 19:35, SviMik <svimik@gmail.com> wrote:
>> Hi, James!
>>
>> No, I'm suffering from kernel panics since I started using 4.x
>> kernels.
> It's interesting that you are seeing l2tp issues since switching to
> 4.x kernels. Are you able to try earlier kernels to find the latest
> version that works? I'm curious whether things broke at v3.15.
It's possible that this may be fixed by a patch that is already
upstream and merged for v4.14. The fix is from Guillaume Nault:
f3c66d4 l2tp: prevent creation of sessions on terminated tunnels
If it's possible that the L2TP server may try to create a session in a
tunnel that is being closed, this bug would be exposed.
Guillaume's fix isn't yet pushed to stable releases. Are you able to
try a v4.14-rc build?
^ permalink raw reply
* [PATCH v2 net-next] ravb: RX checksum offload
From: Simon Horman @ 2017-10-04 7:54 UTC (permalink / raw)
To: David Miller, Sergei Shtylyov
Cc: Magnus Damm, netdev, linux-renesas-soc, Simon Horman
Add support for RX checksum offload. This is enabled by default and
may be disabled and re-enabled using ethtool:
# ethtool -K eth0 rx off
# ethtool -K eth0 rx on
The RAVB provides a simple checksumming scheme which appears to be
completely compatible with CHECKSUM_COMPLETE: sum of all packet data after
the L2 header is appended to packet data; this may be trivially read by the
driver and used to update the skb accordingly.
In terms of performance throughput is close to gigabit line-rate both with
and without RX checksum offload enabled. Perf output, however, appears to
indicate that significantly less time is spent in do_csum(). This is as
expected.
Test results with RX checksum offload enabled:
# /usr/bin/perf_3.16 record -o /run/perf.data -a netperf -t TCP_MAERTS -H 10.4.3.162
MIGRATED TCP MAERTS TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.4.3.162 () port 0 AF_INET : demo
enable_enobufs failed: getprotobyname
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec
87380 16384 16384 10.00 937.54
Summary of output of perf report:
18.28% ksoftirqd/0 [kernel.kallsyms] [k] _raw_spin_unlock_irqrestore
10.34% ksoftirqd/0 [kernel.kallsyms] [k] __pi_memcpy
9.83% ksoftirqd/0 [kernel.kallsyms] [k] ravb_poll
7.89% ksoftirqd/0 [kernel.kallsyms] [k] skb_put
4.01% ksoftirqd/0 [kernel.kallsyms] [k] dev_gro_receive
3.37% netperf [kernel.kallsyms] [k] __arch_copy_to_user
3.17% swapper [kernel.kallsyms] [k] arch_cpu_idle
2.55% swapper [kernel.kallsyms] [k] tick_nohz_idle_enter
2.04% ksoftirqd/0 [kernel.kallsyms] [k] __pi___inval_dcache_area
2.03% swapper [kernel.kallsyms] [k] _raw_spin_unlock_irq
1.96% ksoftirqd/0 [kernel.kallsyms] [k] __netdev_alloc_skb
1.59% ksoftirqd/0 [kernel.kallsyms] [k] __slab_alloc.isra.83
Test results without RX checksum offload enabled:
# /usr/bin/perf_3.16 record -o /run/perf.data -a netperf -t TCP_MAERTS -H 10.4.3.162
MIGRATED TCP MAERTS TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.4.3.162 () port 0 AF_INET : demo
enable_enobufs failed: getprotobyname
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec
87380 16384 16384 10.00 940.20
Summary of output of perf report:
17.10% ksoftirqd/0 [kernel.kallsyms] [k] _raw_spin_unlock_irqrestore
10.99% ksoftirqd/0 [kernel.kallsyms] [k] __pi_memcpy
8.87% ksoftirqd/0 [kernel.kallsyms] [k] ravb_poll
8.16% ksoftirqd/0 [kernel.kallsyms] [k] skb_put
7.42% ksoftirqd/0 [kernel.kallsyms] [k] do_csum
3.91% ksoftirqd/0 [kernel.kallsyms] [k] dev_gro_receive
2.31% swapper [kernel.kallsyms] [k] arch_cpu_idle
2.16% ksoftirqd/0 [kernel.kallsyms] [k] __pi___inval_dcache_area
2.14% ksoftirqd/0 [kernel.kallsyms] [k] __netdev_alloc_skb
1.93% netperf [kernel.kallsyms] [k] __arch_copy_to_user
1.79% swapper [kernel.kallsyms] [k] tick_nohz_idle_enter
1.63% ksoftirqd/0 [kernel.kallsyms] [k] __slab_alloc.isra.83
Above results collected on an R-Car Gen 3 Salvator-X/r8a7796 ES1.0.
Also tested on a R-Car Gen 3 Salvator-X/r8a7795 ES1.0.
By inspection this also appears to be compatible with the ravb found
on R-Car Gen 2 SoCs, however, this patch is currently untested on such
hardware.
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
v2
Address review of v1 by Sergei Shtylyov
* set features rather than oring them with (zero) existing values:
* Set/unset using a single call to ravb_modify()
---
drivers/net/ethernet/renesas/ravb_main.c | 55 +++++++++++++++++++++++++++++++-
1 file changed, 54 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index fdf30bfa403b..a8822a756e08 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -403,8 +403,9 @@ static void ravb_emac_init(struct net_device *ndev)
/* Receive frame limit set register */
ravb_write(ndev, ndev->mtu + ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN, RFLR);
- /* PAUSE prohibition */
+ /* EMAC Mode: PAUSE prohibition; Duplex; RX Checksum; TX; RX */
ravb_write(ndev, ECMR_ZPF | (priv->duplex ? ECMR_DM : 0) |
+ (ndev->features & NETIF_F_RXCSUM ? ECMR_RCSC : 0) |
ECMR_TE | ECMR_RE, ECMR);
ravb_set_rate(ndev);
@@ -520,6 +521,19 @@ static void ravb_get_tx_tstamp(struct net_device *ndev)
}
}
+static void ravb_rx_csum(struct sk_buff *skb)
+{
+ u8 *hw_csum;
+
+ /* The hardware checksum is 2 bytes appended to packet data */
+ if (unlikely(skb->len < 2))
+ return;
+ hw_csum = skb_tail_pointer(skb) - 2;
+ skb->csum = csum_unfold((__force __sum16)get_unaligned_le16(hw_csum));
+ skb->ip_summed = CHECKSUM_COMPLETE;
+ skb_trim(skb, skb->len - 2);
+}
+
/* Packet receive function for Ethernet AVB */
static bool ravb_rx(struct net_device *ndev, int *quota, int q)
{
@@ -587,8 +601,11 @@ static bool ravb_rx(struct net_device *ndev, int *quota, int q)
ts.tv_nsec = le32_to_cpu(desc->ts_n);
shhwtstamps->hwtstamp = timespec64_to_ktime(ts);
}
+
skb_put(skb, pkt_len);
skb->protocol = eth_type_trans(skb, ndev);
+ if (ndev->features & NETIF_F_RXCSUM)
+ ravb_rx_csum(skb);
napi_gro_receive(&priv->napi[q], skb);
stats->rx_packets++;
stats->rx_bytes += pkt_len;
@@ -1842,6 +1859,38 @@ static int ravb_do_ioctl(struct net_device *ndev, struct ifreq *req, int cmd)
return phy_mii_ioctl(phydev, req, cmd);
}
+static void ravb_set_rx_csum(struct net_device *ndev, bool enable)
+{
+ struct ravb_private *priv = netdev_priv(ndev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ /* Disable TX and RX */
+ ravb_rcv_snd_disable(ndev);
+
+ /* Modify RX Checksum setting */
+ ravb_modify(ndev, ECMR, ECMR_RCSC, enable ? ECMR_RCSC : 0);
+
+ /* Enable TX and RX */
+ ravb_rcv_snd_enable(ndev);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static int ravb_set_features(struct net_device *ndev,
+ netdev_features_t features)
+{
+ netdev_features_t changed = ndev->features ^ features;
+
+ if (changed & NETIF_F_RXCSUM)
+ ravb_set_rx_csum(ndev, features & NETIF_F_RXCSUM);
+
+ ndev->features = features;
+
+ return 0;
+}
+
static const struct net_device_ops ravb_netdev_ops = {
.ndo_open = ravb_open,
.ndo_stop = ravb_close,
@@ -1853,6 +1902,7 @@ static const struct net_device_ops ravb_netdev_ops = {
.ndo_do_ioctl = ravb_do_ioctl,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = eth_mac_addr,
+ .ndo_set_features = ravb_set_features,
};
/* MDIO bus init function */
@@ -2004,6 +2054,9 @@ static int ravb_probe(struct platform_device *pdev)
if (!ndev)
return -ENOMEM;
+ ndev->features = NETIF_F_RXCSUM;
+ ndev->hw_features = NETIF_F_RXCSUM;
+
pm_runtime_enable(&pdev->dev);
pm_runtime_get_sync(&pdev->dev);
--
2.1.4
^ permalink raw reply related
* Re: [PATCH net-next 2/2] flow_dissector: dissect tunnel info
From: Simon Horman @ 2017-10-04 8:08 UTC (permalink / raw)
To: Tom Herbert
Cc: David Miller, Jiri Pirko, Jamal Hadi Salim, Cong Wang,
Linux Kernel Network Developers, oss-drivers
In-Reply-To: <CALx6S37K3Gif=AGk48CXs9JgrcDbdpfqMZWK+0j95UHG0hvpZg@mail.gmail.com>
On Tue, Oct 03, 2017 at 11:17:46AM -0700, Tom Herbert wrote:
> On Tue, Oct 3, 2017 at 2:40 AM, Simon Horman <simon.horman@netronome.com> wrote:
> > On Mon, Oct 02, 2017 at 01:37:55PM -0700, Tom Herbert wrote:
> >> On Mon, Oct 2, 2017 at 1:41 AM, Simon Horman <simon.horman@netronome.com> wrote:
> >> > Move dissection of tunnel info from the flower classifier to the flow
> >> > dissector where all other dissection occurs. This should not have any
> >> > behavioural affect on other users of the flow dissector.
> >
> > ...
>
> > I feel that we are circling back the perennial issue of flower using the
> > flow dissector in a somewhat broader/different way than many/all other
> > users of the flow dissector.
> >
> Simon,
>
> It's more like __skb_flow_dissect is already an incredibly complex
> function and because of that it's difficult to maintain. We need to
> measure changes against that fact. For this patch, there is precisely
> one user (cls_flower.c) and it's not at all clear to me if there will
> be ever any more (e.g. for hashing we don't need tunnel info). IMO, it
> should be just as easy and less convolution for everyone to have
> flower call __skb_flow_dissect_tunnel_info directly and not call if
> from __skb_flow_dissect.
Hi Tom,
my original suggestion was just that, but Jiri indicated a strong preference
for the approach taken by this patch. I think we need to widen the
participants in this discussion.
^ permalink raw reply
* Re: [PATCH net-next 2/2] flow_dissector: dissect tunnel info
From: Jiri Pirko @ 2017-10-04 8:15 UTC (permalink / raw)
To: Simon Horman
Cc: Tom Herbert, David Miller, Jiri Pirko, Jamal Hadi Salim,
Cong Wang, Linux Kernel Network Developers, oss-drivers
In-Reply-To: <20171004080856.GB6378@netronome.com>
Wed, Oct 04, 2017 at 10:08:57AM CEST, simon.horman@netronome.com wrote:
>On Tue, Oct 03, 2017 at 11:17:46AM -0700, Tom Herbert wrote:
>> On Tue, Oct 3, 2017 at 2:40 AM, Simon Horman <simon.horman@netronome.com> wrote:
>> > On Mon, Oct 02, 2017 at 01:37:55PM -0700, Tom Herbert wrote:
>> >> On Mon, Oct 2, 2017 at 1:41 AM, Simon Horman <simon.horman@netronome.com> wrote:
>> >> > Move dissection of tunnel info from the flower classifier to the flow
>> >> > dissector where all other dissection occurs. This should not have any
>> >> > behavioural affect on other users of the flow dissector.
>> >
>> > ...
>>
>> > I feel that we are circling back the perennial issue of flower using the
>> > flow dissector in a somewhat broader/different way than many/all other
>> > users of the flow dissector.
>> >
>> Simon,
>>
>> It's more like __skb_flow_dissect is already an incredibly complex
>> function and because of that it's difficult to maintain. We need to
>> measure changes against that fact. For this patch, there is precisely
>> one user (cls_flower.c) and it's not at all clear to me if there will
>> be ever any more (e.g. for hashing we don't need tunnel info). IMO, it
>> should be just as easy and less convolution for everyone to have
>> flower call __skb_flow_dissect_tunnel_info directly and not call if
>> from __skb_flow_dissect.
>
>Hi Tom,
>
>my original suggestion was just that, but Jiri indicated a strong preference
>for the approach taken by this patch. I think we need to widen the
>participants in this discussion.
I like the __skb_flow_dissect to be the function to call and it will do
the job according to the configuration. I don't like to split in
multiple calls. Does not make sense in the most of the cases as the
dissection state would have to be carried in between calls.
^ permalink raw reply
* Re: [PATCH net-next 3/3] Move shared tcp code to net/ipv4v6shared
From: Richard Siegfried @ 2017-10-04 8:57 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev, David Miller, yoshfuji, kuznet
In-Reply-To: <CAOaVG14r2Uwm+r17Oa9jwKj50vRr8=SqwXEmmGAeW8rHj3FgXg@mail.gmail.com>
[-- Attachment #1.1: Type: text/plain, Size: 428 bytes --]
On 04/10/17 03:32, Stephen Hemminger wrote:
> The name ipv4v6_shared is longer than it needs to be maybe ip or ip_common
Well ip_common sounds nice.
But I don't fully understand what this means for the current situation.
I could do a v2, but would that make any sense since Dave and Eric
already said "no" to the whole concept.
Would it change anything to keep the tcp directory in net/ipv4/ (only
1/3 and 2/3)?
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 529 bytes --]
^ permalink raw reply
* Re: [PATCH v3 1/2] dt-bindings: add device tree binding for Allwinner XR819 SDIO Wi-Fi
From: Kalle Valo @ 2017-10-04 9:02 UTC (permalink / raw)
To: Icenowy Zheng
Cc: Rob Herring, Maxime Ripard, Chen-Yu Tsai,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
In-Reply-To: <20171003165944.13056-2-icenowy-h8G6r0blFSE@public.gmane.org>
Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org> writes:
> Allwinner XR819 is a SDIO Wi-Fi chip, which has the functionality to use
> an out-of-band interrupt pin instead of SDIO in-band interrupt.
>
> Add the device tree binding of this chip, in order to make it possible
> to add this interrupt pin to device trees.
>
> Signed-off-by: Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
> Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> ---
> Changes in v3:
> - Renames the node name.
> - Adds ACK from Rob.
> Changes in v2:
> - Removed status property in example.
> - Added required property reg.
>
> .../bindings/net/wireless/allwinner,xr819.txt | 38 ++++++++++++++++++++++
> 1 file changed, 38 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/net/wireless/allwinner,xr819.txt
Like I asked already last time, AFAICS there is no upstream xr819
wireless driver in drivers/net/wireless directory. Do we still accept
bindings like this for out-of-tree drivers?
--
Kalle Valo
^ permalink raw reply
* Re: [PATCH v3 1/2] dt-bindings: add device tree binding for Allwinner XR819 SDIO Wi-Fi
From: Icenowy Zheng @ 2017-10-04 9:03 UTC (permalink / raw)
To: Kalle Valo
Cc: Rob Herring, Maxime Ripard, Chen-Yu Tsai,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
In-Reply-To: <871smjxp46.fsf-HodKDYzPHsUD5k0oWYwrnHL1okKdlPRT@public.gmane.org>
于 2017年10月4日 GMT+08:00 下午5:02:17, Kalle Valo <kvalo-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org> 写到:
>Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org> writes:
>
>> Allwinner XR819 is a SDIO Wi-Fi chip, which has the functionality to
>use
>> an out-of-band interrupt pin instead of SDIO in-band interrupt.
>>
>> Add the device tree binding of this chip, in order to make it
>possible
>> to add this interrupt pin to device trees.
>>
>> Signed-off-by: Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
>> Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>> ---
>> Changes in v3:
>> - Renames the node name.
>> - Adds ACK from Rob.
>> Changes in v2:
>> - Removed status property in example.
>> - Added required property reg.
>>
>> .../bindings/net/wireless/allwinner,xr819.txt | 38
>++++++++++++++++++++++
>> 1 file changed, 38 insertions(+)
>> create mode 100644
>Documentation/devicetree/bindings/net/wireless/allwinner,xr819.txt
>
>Like I asked already last time, AFAICS there is no upstream xr819
>wireless driver in drivers/net/wireless directory. Do we still accept
>bindings like this for out-of-tree drivers?
See esp8089.
There's also no in-tree driver for it.
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
^ permalink raw reply
* Re: ath9k: make const array reg_hole_list static, reduces object code size
From: Kalle Valo @ 2017-10-04 9:09 UTC (permalink / raw)
To: Colin Ian King
Cc: QCA ath9k Development, Kalle Valo, linux-wireless, netdev,
kernel-janitors, linux-kernel
In-Reply-To: <20170919204019.30804-1-colin.king@canonical.com>
Colin Ian King <colin.king@canonical.com> wrote:
> Don't populate the read-only array reg_hole_list on the stack, instead make
> it static. Makes the object code smaller by over 200 bytes:
>
> Before:
> text data bss dec hex filename
> 57518 15248 0 72766 11c3e debug.o
>
> After:
> text data bss dec hex filename
> 57218 15344 0 72562 11b72 debug.o
>
> Signed-off-by: Colin Ian King <colin.king@canonical.com>
> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Patch applied to ath-next branch of ath.git, thanks.
eba0f28473b2 ath9k: make const array reg_hole_list static, reduces object code size
--
https://patchwork.kernel.org/patch/9960183/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* RE: [PATCH] fsl/fman: remove of_node
From: Madalin-cristian Bucur @ 2017-10-04 9:53 UTC (permalink / raw)
To: David Miller
Cc: netdev@vger.kernel.org, andrew@lunn.ch, f.fainelli@gmail.com,
linux-kernel@vger.kernel.org
In-Reply-To: <20171003.214357.2276688669726195045.davem@davemloft.net>
> -----Original Message-----
> From: David Miller [mailto:davem@davemloft.net]
> Sent: Wednesday, October 04, 2017 7:44 AM
> To: Madalin-cristian Bucur <madalin.bucur@nxp.com>
> Cc: netdev@vger.kernel.org; andrew@lunn.ch; f.fainelli@gmail.com; linux-
> kernel@vger.kernel.org
> Subject: Re: [PATCH] fsl/fman: remove of_node
>
> From: Madalin-cristian Bucur <madalin.bucur@nxp.com>
> Date: Tue, 3 Oct 2017 08:49:31 +0000
>
> > My patch removes the of_node that was set to a device that was not an
> > of_device, preventing duplicated probing of both the real of_device
> > and the "fake" one created through this assignment.
> >
> > I understand that the DSA issue that triggered the initial change
> > was related to DSA finding the network devices using
> > of_find_net_device_by_node(), something that will not work for the
> > DPAA case where the netdevice does not have an of_node. I do not know
> > enough about DSA to come up with a solution for this problem now.
> > Andrew, Florian, can you please comment on this?
>
> It sounds like you're knowingly breaking DSA.
It never worked, even with the change I'm reverting.
^ permalink raw reply
* RE: [PATCH] fsl/fman: remove of_node
From: Madalin-cristian Bucur @ 2017-10-04 9:59 UTC (permalink / raw)
To: Andrew Lunn
Cc: David Miller, netdev@vger.kernel.org, f.fainelli@gmail.com,
linux-kernel@vger.kernel.org
In-Reply-To: <20171003130032.GI13548@lunn.ch>
> -----Original Message-----
> From: Andrew Lunn [mailto:andrew@lunn.ch]
> Sent: Tuesday, October 03, 2017 4:01 PM
> To: Madalin-cristian Bucur <madalin.bucur@nxp.com>
> Cc: David Miller <davem@davemloft.net>; netdev@vger.kernel.org;
> f.fainelli@gmail.com; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH] fsl/fman: remove of_node
>
> On Tue, Oct 03, 2017 at 08:49:31AM +0000, Madalin-cristian Bucur wrote:
> > > -----Original Message-----
> > > From: David Miller [mailto:davem@davemloft.net]
> > > Sent: Tuesday, October 03, 2017 2:05 AM
> > > To: Madalin-cristian Bucur <madalin.bucur@nxp.com>
> > > Subject: Re: [PATCH] fsl/fman: remove of_node
> > >
> > > From: Madalin Bucur <madalin.bucur@nxp.com>
> > > Date: Mon, 2 Oct 2017 13:31:37 +0300
> > >
> > > > The FMan MAC driver allocates a platform device for the Ethernet
> > > > driver to probe on. Setting pdev->dev.of_node with the MAC node
> > > > triggers the MAC driver probing of the new platform device. While
> > > > this fails quickly and does not affect the functionality of the
> > > > drivers, it is incorrect and must be removed. This was added to
> > > > address a report that DSA code using of_find_net_device_by_node()
> > > > is unable to use the DPAA interfaces. Error message seen before
> > > > this fix:
> > > >
> > > > fsl_mac dpaa-ethernet.0: __devm_request_mem_region(mac) failed
> > > > fsl_mac: probe of dpaa-ethernet.0 failed with error -16
> > > >
> > > > Signed-off-by: Madalin Bucur <madalin.bucur@nxp.com>
> > >
> > > Is the DSA issue no longer something we need to be concerned
> > > about? If not, why? You have to explain this.
> >
> > My patch removes the of_node that was set to a device that was not an
> > of_device, preventing duplicated probing of both the real of_device
> > and the "fake" one created through this assignment.
> >
> > I understand that the DSA issue that triggered the initial change
> > was related to DSA finding the network devices using
> > of_find_net_device_by_node(), something that will not work for the
> > DPAA case where the netdevice does not have an of_node. I do not know
> > enough about DSA to come up with a solution for this problem now.
> > Andrew, Florian, can you please comment on this?
> >
> > Thanks,
>
> Hi Madalin
>
> I guess the real fix is to throw away the platform device. But that is
> a big change.
>
> I've not looked at the code in detail. Why is the platform device
> needed?
>
> Andrew
There are multiple components that are aggregated by the DPAA Ethernet
netdevice, the FMan MAC is one of them. There is no entry in the device
tree for the Ethernet device as this is just a software construct that
binds together multiple pieces from the DPAA FMan, QMan, BMan. The probing
of the Ethernet driver is performed against a platform device that is created
in the FMan MAC. Setting the of_node in the new platform device makes it
look like an of_device without being one, thus the errors at the MAC driver
probing against the platform device.
Does DSA work for systems that do not use a device tree to boot, i.e. ACPI?
Madalin
^ permalink raw reply
* Re: [PATCH v3 1/2] dt-bindings: add device tree binding for Allwinner XR819 SDIO Wi-Fi
From: 'Arend van Spriel' via linux-sunxi @ 2017-10-04 10:02 UTC (permalink / raw)
To: Icenowy Zheng, Kalle Valo
Cc: Rob Herring, Maxime Ripard, Chen-Yu Tsai,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
In-Reply-To: <E46F3A20-294A-497E-AF71-C77A67AFDB8C-h8G6r0blFSE@public.gmane.org>
On 10/4/2017 11:03 AM, Icenowy Zheng wrote:
>
>
> 于 2017年10月4日 GMT+08:00 下午5:02:17, Kalle Valo <kvalo-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org> 写到:
>> Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org> writes:
>>
>>> Allwinner XR819 is a SDIO Wi-Fi chip, which has the functionality to
>> use
>>> an out-of-band interrupt pin instead of SDIO in-band interrupt.
>>>
>>> Add the device tree binding of this chip, in order to make it
>> possible
>>> to add this interrupt pin to device trees.
>>>
>>> Signed-off-by: Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
>>> Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>>> ---
>>> Changes in v3:
>>> - Renames the node name.
>>> - Adds ACK from Rob.
>>> Changes in v2:
>>> - Removed status property in example.
>>> - Added required property reg.
>>>
>>> .../bindings/net/wireless/allwinner,xr819.txt | 38
>> ++++++++++++++++++++++
>>> 1 file changed, 38 insertions(+)
>>> create mode 100644
>> Documentation/devicetree/bindings/net/wireless/allwinner,xr819.txt
>>
>> Like I asked already last time, AFAICS there is no upstream xr819
>> wireless driver in drivers/net/wireless directory. Do we still accept
>> bindings like this for out-of-tree drivers?
>
> See esp8089.
>
> There's also no in-tree driver for it.
The question is whether we should. The above might be a precedent, but
it may not necessarily be the way to go. The commit message for esp8089
seems to hint that there is intent to have an in-tree driver:
"""
Note that at this point there only is an out of tree driver for this
hardware, there is no clear timeline / path for merging this. Still
I believe it would be good to specify the binding for this in tree
now, so that any future migration to an in tree driver will not cause
compatiblity issues.
Cc: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
"""
Regardless the bindings are in principle independent of the kernel and
just describing hardware. I think there have been discussions to move
the bindings to their own repository, but apparently it was decided
otherwise.
Regards,
Arend
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
^ permalink raw reply
* Re: [PATCH v3 1/2] dt-bindings: add device tree binding for Allwinner XR819 SDIO Wi-Fi
From: Maxime Ripard @ 2017-10-04 10:11 UTC (permalink / raw)
To: Arend van Spriel
Cc: Icenowy Zheng, Kalle Valo, Rob Herring, Chen-Yu Tsai,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
In-Reply-To: <59D4B1C8.8020105-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 3135 bytes --]
On Wed, Oct 04, 2017 at 10:02:48AM +0000, Arend van Spriel wrote:
> On 10/4/2017 11:03 AM, Icenowy Zheng wrote:
> >
> >
> > 于 2017年10月4日 GMT+08:00 下午5:02:17, Kalle Valo <kvalo-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org> 写到:
> > > Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org> writes:
> > >
> > > > Allwinner XR819 is a SDIO Wi-Fi chip, which has the functionality to
> > > use
> > > > an out-of-band interrupt pin instead of SDIO in-band interrupt.
> > > >
> > > > Add the device tree binding of this chip, in order to make it
> > > possible
> > > > to add this interrupt pin to device trees.
> > > >
> > > > Signed-off-by: Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
> > > > Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> > > > ---
> > > > Changes in v3:
> > > > - Renames the node name.
> > > > - Adds ACK from Rob.
> > > > Changes in v2:
> > > > - Removed status property in example.
> > > > - Added required property reg.
> > > >
> > > > .../bindings/net/wireless/allwinner,xr819.txt | 38
> > > ++++++++++++++++++++++
> > > > 1 file changed, 38 insertions(+)
> > > > create mode 100644
> > > Documentation/devicetree/bindings/net/wireless/allwinner,xr819.txt
> > >
> > > Like I asked already last time, AFAICS there is no upstream xr819
> > > wireless driver in drivers/net/wireless directory. Do we still accept
> > > bindings like this for out-of-tree drivers?
> >
> > See esp8089.
> >
> > There's also no in-tree driver for it.
>
> The question is whether we should. The above might be a precedent, but it
> may not necessarily be the way to go. The commit message for esp8089 seems
> to hint that there is intent to have an in-tree driver:
>
> """
> Note that at this point there only is an out of tree driver for this
> hardware, there is no clear timeline / path for merging this. Still
> I believe it would be good to specify the binding for this in tree
> now, so that any future migration to an in tree driver will not cause
> compatiblity issues.
>
> Cc: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> Signed-off-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> """
>
> Regardless the bindings are in principle independent of the kernel and just
> describing hardware. I think there have been discussions to move the
> bindings to their own repository, but apparently it was decided otherwise.
Yeah, I guess especially how it could be merged with the cw1200 driver
would be very relevant to that commit log.
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
* Re: [PATCH v3 1/2] dt-bindings: add device tree binding for Allwinner XR819 SDIO Wi-Fi
From: Icenowy Zheng @ 2017-10-04 10:15 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Maxime Ripard,
Arend van Spriel
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Chen-Yu Tsai, Rob Herring,
Kalle Valo
In-Reply-To: <20171004101145.kgjufpcktodppuy3@flea>
于 2017年10月4日 GMT+08:00 下午6:11:45, Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> 写到:
>On Wed, Oct 04, 2017 at 10:02:48AM +0000, Arend van Spriel wrote:
>> On 10/4/2017 11:03 AM, Icenowy Zheng wrote:
>> >
>> >
>> > 于 2017年10月4日 GMT+08:00 下午5:02:17, Kalle Valo <kvalo-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
>写到:
>> > > Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org> writes:
>> > >
>> > > > Allwinner XR819 is a SDIO Wi-Fi chip, which has the
>functionality to
>> > > use
>> > > > an out-of-band interrupt pin instead of SDIO in-band interrupt.
>> > > >
>> > > > Add the device tree binding of this chip, in order to make it
>> > > possible
>> > > > to add this interrupt pin to device trees.
>> > > >
>> > > > Signed-off-by: Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
>> > > > Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>> > > > ---
>> > > > Changes in v3:
>> > > > - Renames the node name.
>> > > > - Adds ACK from Rob.
>> > > > Changes in v2:
>> > > > - Removed status property in example.
>> > > > - Added required property reg.
>> > > >
>> > > > .../bindings/net/wireless/allwinner,xr819.txt | 38
>> > > ++++++++++++++++++++++
>> > > > 1 file changed, 38 insertions(+)
>> > > > create mode 100644
>> > >
>Documentation/devicetree/bindings/net/wireless/allwinner,xr819.txt
>> > >
>> > > Like I asked already last time, AFAICS there is no upstream xr819
>> > > wireless driver in drivers/net/wireless directory. Do we still
>accept
>> > > bindings like this for out-of-tree drivers?
>> >
>> > See esp8089.
>> >
>> > There's also no in-tree driver for it.
>>
>> The question is whether we should. The above might be a precedent,
>but it
>> may not necessarily be the way to go. The commit message for esp8089
>seems
>> to hint that there is intent to have an in-tree driver:
>>
>> """
>> Note that at this point there only is an out of tree driver for
>this
>> hardware, there is no clear timeline / path for merging this.
>Still
>> I believe it would be good to specify the binding for this in
>tree
>> now, so that any future migration to an in tree driver will not
>cause
>> compatiblity issues.
>>
>> Cc: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
>> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
>> Signed-off-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>> """
>>
>> Regardless the bindings are in principle independent of the kernel
>and just
>> describing hardware. I think there have been discussions to move the
>> bindings to their own repository, but apparently it was decided
>otherwise.
>
>Yeah, I guess especially how it could be merged with the cw1200 driver
>would be very relevant to that commit log.
The cw1200 driver seems to still have some legacy platform
data. Maybe they should also be convert to DT.
(Or maybe compatible = "allwinner,xr819" is enough, as
xr819 is a specified variant of cw1200 family)
>
>Maxime
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
^ permalink raw reply
* Re: Fw: [Bug 197099] New: Kernel panic in interrupt [l2tp_ppp]
From: Guillaume Nault @ 2017-10-04 10:33 UTC (permalink / raw)
To: James Chapman; +Cc: SviMik, netdev
In-Reply-To: <CAEwTi7SS7qsbV19NsPGwdiwTcejxygUEqQi-_MJ07uMec0CY9A@mail.gmail.com>
On Wed, Oct 04, 2017 at 08:49:51AM +0100, James Chapman wrote:
> On 3 October 2017 at 08:27, James Chapman <jchapman@katalix.com> wrote:
> > On 2 October 2017 at 19:35, SviMik <svimik@gmail.com> wrote:
> >> Hi, James!
> >>
> >> No, I'm suffering from kernel panics since I started using 4.x
> >> kernels.
> > It's interesting that you are seeing l2tp issues since switching to
> > 4.x kernels. Are you able to try earlier kernels to find the latest
> > version that works? I'm curious whether things broke at v3.15.
>
> It's possible that this may be fixed by a patch that is already
> upstream and merged for v4.14. The fix is from Guillaume Nault:
>
> f3c66d4 l2tp: prevent creation of sessions on terminated tunnels
>
> If it's possible that the L2TP server may try to create a session in a
> tunnel that is being closed, this bug would be exposed.
>
Yes, I think this patch is worth a try. In the case of sessions created
on a dead tunnel, I wouldn't have expected the xmit path to even reach
l2tp_xmit_skb() though (that's certainly possible, but the timing
constraints look a bit hard to reach).
BTW, I started working on this issue a few days ago and came to the
same conclusions as the ones you posted in your previous replies. Given
that we were in line with the analysis, I've switched to the PPP bug
reported by Beniamino (https://www.spinics.net/lists/netdev/msg458002.html).
I'll move back to L2TP as soon as possible.
^ permalink raw reply
* Re: [PATCH] rndis_host: support Novatel Verizon USB730L
From: Oliver Neukum @ 2017-10-04 10:44 UTC (permalink / raw)
To: Bjørn Mork, David Miller; +Cc: aleksander, linux-usb, netdev
In-Reply-To: <87k20cmitw.fsf@miraculix.mork.no>
Am Dienstag, den 03.10.2017, 16:01 +0200 schrieb Bjørn Mork:
> Adding anything else, e.g. based on the table at
> http://www.usb.org/developers/defined_class/#BaseClassEFh , is a bit
> more risky. We don't know if a driver will work with *any* such device
> until we've actually seen one.
>
> This is just my opinion, and probably full of bogus assumptions as
> usual. I was sort of hoping that some expert would speak up so I didn't
> have to :-)
Outside the vendors, there is nobody.
Regards
Oliver
^ permalink raw reply
* multi producer / multi consumer lock-free queue with ptr_ring
From: Jason A. Donenfeld @ 2017-10-04 11:18 UTC (permalink / raw)
To: Michael S. Tsirkin; +Cc: LKML, Netdev, Samuel Holland, WireGuard mailing list
Hey Michael,
Thanks for your work on ptr_ring.h. I'm interested in using it, but in
a multi-producer, multi-consumer context. I realize it's been designed
for a single-producer, single-consumer context, and thus uses a
spinlock. I'm wondering if you'd be happy to receive patches that
implement things in a lock-free way, in order to make the data
structure more broadly usable.
In case you're curious, this would be used for the multi-core
algorithms in WireGuard.
Thanks,
Jason
^ permalink raw reply
* Re: [PATCH net-next v2 0/3] tools: add bpftool
From: Arnaldo Carvalho de Melo @ 2017-10-04 11:40 UTC (permalink / raw)
To: Jakub Kicinski; +Cc: netdev, daniel, alexei.starovoitov, oss-drivers
In-Reply-To: <20171003174822.214e4337@cakuba>
Em Tue, Oct 03, 2017 at 05:48:22PM -0700, Jakub Kicinski escreveu:
> On Tue, 3 Oct 2017 17:19:42 -0300, Arnaldo Carvalho de Melo wrote:
> > Why not call it just 'bpf'?
> bpftool was suggested as a better name, I don't really mind either way.
I just thought that 'bpf' isn't used as a command, shorter, less typing,
but yeah, if people think having 'tool' in the tool name helps somewhat,
so be it.
- Arnaldo
^ permalink raw reply
* [PATCH net-next] selftests: rtnetlink: try concurrent change of ifalias
From: Florian Westphal @ 2017-10-04 11:52 UTC (permalink / raw)
To: netdev; +Cc: Florian Westphal
to make sure this is serialized correctly.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
tools/testing/selftests/net/rtnetlink.sh | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/tools/testing/selftests/net/rtnetlink.sh b/tools/testing/selftests/net/rtnetlink.sh
index 62c87da92770..13c29beb5769 100755
--- a/tools/testing/selftests/net/rtnetlink.sh
+++ b/tools/testing/selftests/net/rtnetlink.sh
@@ -278,6 +278,14 @@ kci_test_ifalias()
ip link show "$devdummy" | grep -q "alias $namewant"
check_fail $?
+ for i in $(seq 1 100); do
+ uuidgen > "$syspathname" &
+ done
+
+ for i in $(seq 1 100); do
+ wait
+ done
+
# re-add the alias -- kernel should free mem when dummy dev is removed
ip link set dev "$devdummy" alias "$namewant"
check_err $?
--
2.13.6
^ permalink raw reply related
* [PATCH net-next] net: core: fix kerneldoc comment
From: Florian Westphal @ 2017-10-04 11:56 UTC (permalink / raw)
To: netdev; +Cc: Florian Westphal
net/core/dev.c:1306: warning: No description found for parameter 'name'
net/core/dev.c:1306: warning: Excess function parameter 'alias' description in 'dev_get_alias'
Fixes: 6c5570016b97 ("net: core: decouple ifalias get/set from rtnl lock")
Reported-by: kbuild test robot <fengguang.wu@intel.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
net/core/dev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index 1770097cfd86..454f05441546 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1295,7 +1295,7 @@ int dev_set_alias(struct net_device *dev, const char *alias, size_t len)
/**
* dev_get_alias - get ifalias of a device
* @dev: device
- * @alias: buffer to store name of ifalias
+ * @name: buffer to store name of ifalias
* @len: size of buffer
*
* get ifalias for a device. Caller must make sure dev cannot go
--
2.13.6
^ permalink raw reply related
* [PATCH net-next] openvswitch: Add erspan tunnel support.
From: William Tu @ 2017-10-04 12:02 UTC (permalink / raw)
To: netdev; +Cc: Pravin B Shelar
Add type II erspan vport implementation. Since erspan protocol is
on top of the GRE header, the implementation is extended from the
existing gre implementation.
Signed-off-by: William Tu <u9012063@gmail.com>
Cc: Pravin B Shelar <pshelar@ovn.org>
---
include/net/gre.h | 2 ++
include/uapi/linux/openvswitch.h | 2 ++
net/ipv4/ip_gre.c | 45 ++++++++++++++++++++++++++
net/openvswitch/flow_netlink.c | 55 +++++++++++++++++++++++++++++++-
net/openvswitch/vport-gre.c | 68 ++++++++++++++++++++++++++++++++++++++--
5 files changed, 169 insertions(+), 3 deletions(-)
diff --git a/include/net/gre.h b/include/net/gre.h
index d25d836c129b..6aa213a5502b 100644
--- a/include/net/gre.h
+++ b/include/net/gre.h
@@ -33,6 +33,8 @@ int gre_del_protocol(const struct gre_protocol *proto, u8 version);
struct net_device *gretap_fb_dev_create(struct net *net, const char *name,
u8 name_assign_type);
+struct net_device *erspan_fb_dev_create(struct net *net, const char *name,
+ u8 name_assign_type);
int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi,
bool *csum_err, __be16 proto, int nhs);
diff --git a/include/uapi/linux/openvswitch.h b/include/uapi/linux/openvswitch.h
index 156ee4cab82e..2ebe0013ecfb 100644
--- a/include/uapi/linux/openvswitch.h
+++ b/include/uapi/linux/openvswitch.h
@@ -213,6 +213,7 @@ enum ovs_vport_type {
OVS_VPORT_TYPE_GRE, /* GRE tunnel. */
OVS_VPORT_TYPE_VXLAN, /* VXLAN tunnel. */
OVS_VPORT_TYPE_GENEVE, /* Geneve tunnel. */
+ OVS_VPORT_TYPE_ERSPAN, /* ERSPAN tunnel. */
__OVS_VPORT_TYPE_MAX
};
@@ -359,6 +360,7 @@ enum ovs_tunnel_key_attr {
OVS_TUNNEL_KEY_ATTR_IPV6_SRC, /* struct in6_addr src IPv6 address. */
OVS_TUNNEL_KEY_ATTR_IPV6_DST, /* struct in6_addr dst IPv6 address. */
OVS_TUNNEL_KEY_ATTR_PAD,
+ OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS, /* be32 ERSPAN index. */
__OVS_TUNNEL_KEY_ATTR_MAX
};
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index b279c325c7f6..9adba017268d 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -1552,6 +1552,51 @@ static struct pernet_operations ipgre_tap_net_ops = {
.size = sizeof(struct ip_tunnel_net),
};
+struct net_device *erspan_fb_dev_create(struct net *net, const char *name,
+ u8 name_assign_type)
+{
+ struct nlattr *tb[IFLA_MAX + 1];
+ struct net_device *dev;
+ LIST_HEAD(list_kill);
+ struct ip_tunnel *t;
+ int err;
+
+ memset(&tb, 0, sizeof(tb));
+
+ dev = rtnl_create_link(net, name, name_assign_type,
+ &erspan_link_ops, tb);
+ if (IS_ERR(dev))
+ return dev;
+
+ /* Configure flow based ERSPAN device. */
+ t = netdev_priv(dev);
+ t->collect_md = true;
+
+ err = ipgre_newlink(net, dev, tb, NULL, NULL);
+ if (err < 0) {
+ free_netdev(dev);
+ return ERR_PTR(err);
+ }
+
+ /* openvswitch users expect packet sizes to be unrestricted,
+ * so set the largest MTU we can.
+ */
+ err = __ip_tunnel_change_mtu(dev, IP_MAX_MTU, false);
+ if (err)
+ goto out;
+
+ err = rtnl_configure_link(dev, NULL);
+ if (err < 0)
+ goto out;
+
+ return dev;
+out:
+ ip_tunnel_dellink(dev, &list_kill);
+ unregister_netdevice_many(&list_kill);
+ return ERR_PTR(err);
+}
+EXPORT_SYMBOL_GPL(erspan_fb_dev_create);
+
static int __net_init erspan_init_net(struct net *net)
{
return ip_tunnel_init_net(net, erspan_net_id,
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
index e8eb427ce6d1..e0c7e28710f0 100644
--- a/net/openvswitch/flow_netlink.c
+++ b/net/openvswitch/flow_netlink.c
@@ -48,6 +48,7 @@
#include <net/ndisc.h>
#include <net/mpls.h>
#include <net/vxlan.h>
+#include <net/erspan.h>
#include "flow_netlink.h"
@@ -319,7 +320,8 @@ size_t ovs_tun_key_attr_size(void)
* OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS and covered by it.
*/
+ nla_total_size(2) /* OVS_TUNNEL_KEY_ATTR_TP_SRC */
- + nla_total_size(2); /* OVS_TUNNEL_KEY_ATTR_TP_DST */
+ + nla_total_size(2) /* OVS_TUNNEL_KEY_ATTR_TP_DST */
+ + nla_total_size(4); /* OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS */
}
size_t ovs_key_attr_size(void)
@@ -371,6 +373,7 @@ static const struct ovs_len_tbl ovs_tunnel_key_lens[OVS_TUNNEL_KEY_ATTR_MAX + 1]
.next = ovs_vxlan_ext_key_lens },
[OVS_TUNNEL_KEY_ATTR_IPV6_SRC] = { .len = sizeof(struct in6_addr) },
[OVS_TUNNEL_KEY_ATTR_IPV6_DST] = { .len = sizeof(struct in6_addr) },
+ [OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS] = { .len = sizeof(u32) },
};
/* The size of the argument for each %OVS_KEY_ATTR_* Netlink attribute. */
@@ -593,6 +596,37 @@ static int vxlan_tun_opt_from_nlattr(const struct nlattr *attr,
return 0;
}
+static int erspan_tun_opt_from_nlattr(const struct nlattr *attr,
+ struct sw_flow_match *match, bool is_mask,
+ bool log)
+{
+ unsigned long opt_key_offset;
+ struct erspan_metadata opts;
+
+ BUILD_BUG_ON(sizeof(opts) > sizeof(match->key->tun_opts));
+
+ memset(&opts, 0, sizeof(opts));
+ opts.index = nla_get_be32(attr);
+
+ /* Index has only 20-bit */
+ if (ntohl(opts.index) & ~INDEX_MASK) {
+ OVS_NLERR(log, "ERSPAN index number %x too large.",
+ ntohl(opts.index));
+ return -EINVAL;
+ }
+
+ if (!is_mask)
+ SW_FLOW_KEY_PUT(match, tun_opts_len, sizeof(opts), false);
+ else
+ SW_FLOW_KEY_PUT(match, tun_opts_len, 0xff, true);
+
+ opt_key_offset = TUN_METADATA_OFFSET(sizeof(opts));
+ SW_FLOW_KEY_MEMCPY_OFFSET(match, opt_key_offset, &opts, sizeof(opts),
+ is_mask);
+
+ return 0;
+}
+
static int ip_tun_from_nlattr(const struct nlattr *attr,
struct sw_flow_match *match, bool is_mask,
bool log)
@@ -700,6 +734,19 @@ static int ip_tun_from_nlattr(const struct nlattr *attr,
break;
case OVS_TUNNEL_KEY_ATTR_PAD:
break;
+ case OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS:
+ if (opts_type) {
+ OVS_NLERR(log, "Multiple metadata blocks provided");
+ return -EINVAL;
+ }
+
+ err = erspan_tun_opt_from_nlattr(a, match, is_mask, log);
+ if (err)
+ return err;
+
+ tun_flags |= TUNNEL_ERSPAN_OPT;
+ opts_type = type;
+ break;
default:
OVS_NLERR(log, "Unknown IP tunnel attribute %d",
type);
@@ -824,6 +871,10 @@ static int __ip_tun_to_nlattr(struct sk_buff *skb,
else if (output->tun_flags & TUNNEL_VXLAN_OPT &&
vxlan_opt_to_nlattr(skb, tun_opts, swkey_tun_opts_len))
return -EMSGSIZE;
+ else if (output->tun_flags & TUNNEL_ERSPAN_OPT &&
+ nla_put_be32(skb, OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS,
+ ((struct erspan_metadata *)tun_opts)->index))
+ return -EMSGSIZE;
}
return 0;
@@ -2195,6 +2246,8 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
break;
case OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS:
break;
+ case OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS:
+ break;
}
};
diff --git a/net/openvswitch/vport-gre.c b/net/openvswitch/vport-gre.c
index 0e72d95b0e8f..bd4e3b4ec2ec 100644
--- a/net/openvswitch/vport-gre.c
+++ b/net/openvswitch/vport-gre.c
@@ -48,6 +48,49 @@
#include "vport-netdev.h"
static struct vport_ops ovs_gre_vport_ops;
+static struct vport_ops ovs_erspan_vport_ops;
+
+static struct vport *erspan_tnl_create(const struct vport_parms *parms)
+{
+ struct net *net = ovs_dp_get_net(parms->dp);
+ struct net_device *dev;
+ struct vport *vport;
+ int err;
+
+ vport = ovs_vport_alloc(0, &ovs_erspan_vport_ops, parms);
+ if (IS_ERR(vport))
+ return vport;
+
+ rtnl_lock();
+ dev = erspan_fb_dev_create(net, parms->name, NET_NAME_USER);
+ if (IS_ERR(dev)) {
+ rtnl_unlock();
+ ovs_vport_free(vport);
+ return ERR_CAST(dev);
+ }
+
+ err = dev_change_flags(dev, dev->flags | IFF_UP);
+ if (err < 0) {
+ rtnl_delete_link(dev);
+ rtnl_unlock();
+ ovs_vport_free(vport);
+ return ERR_PTR(err);
+ }
+
+ rtnl_unlock();
+ return vport;
+}
+
+static struct vport *erspan_create(const struct vport_parms *parms)
+{
+ struct vport *vport;
+
+ vport = erspan_tnl_create(parms);
+ if (IS_ERR(vport))
+ return vport;
+
+ return ovs_netdev_link(vport, parms->name);
+}
static struct vport *gre_tnl_create(const struct vport_parms *parms)
{
@@ -98,19 +141,40 @@ static struct vport_ops ovs_gre_vport_ops = {
.destroy = ovs_netdev_tunnel_destroy,
};
+static struct vport_ops ovs_erspan_vport_ops = {
+ .type = OVS_VPORT_TYPE_ERSPAN,
+ .create = erspan_create,
+ .send = dev_queue_xmit,
+ .destroy = ovs_netdev_tunnel_destroy,
+};
+
static int __init ovs_gre_tnl_init(void)
{
- return ovs_vport_ops_register(&ovs_gre_vport_ops);
+ int ret;
+
+ ret = ovs_vport_ops_register(&ovs_gre_vport_ops);
+ if (ret)
+ return ret;
+
+ ret = ovs_vport_ops_register(&ovs_erspan_vport_ops);
+ if (ret) {
+ ovs_vport_ops_unregister(&ovs_gre_vport_ops);
+ return ret;
+ }
+
+ return ret;
}
static void __exit ovs_gre_tnl_exit(void)
{
ovs_vport_ops_unregister(&ovs_gre_vport_ops);
+ ovs_vport_ops_unregister(&ovs_erspan_vport_ops);
}
module_init(ovs_gre_tnl_init);
module_exit(ovs_gre_tnl_exit);
-MODULE_DESCRIPTION("OVS: GRE switching port");
+MODULE_DESCRIPTION("OVS: GRE/ERSPAN switching port");
MODULE_LICENSE("GPL");
MODULE_ALIAS("vport-type-3");
+MODULE_ALIAS("vport-type-6");
--
2.7.4
^ permalink raw reply related
* [net-next V4 PATCH 0/5] New bpf cpumap type for XDP_REDIRECT
From: Jesper Dangaard Brouer @ 2017-10-04 12:03 UTC (permalink / raw)
To: netdev
Cc: jakub.kicinski, Michael S. Tsirkin, pavel.odintsov, Jason Wang,
mchan, John Fastabend, peter.waskiewicz.jr,
Jesper Dangaard Brouer, Daniel Borkmann, Alexei Starovoitov,
Andy Gospodarek
Introducing a new way to redirect XDP frames. Notice how no driver
changes are necessary given the design of XDP_REDIRECT.
This redirect map type is called 'cpumap', as it allows redirection
XDP frames to remote CPUs. The remote CPU will do the SKB allocation
and start the network stack invocation on that CPU.
This is a scalability and isolation mechanism, that allow separating
the early driver network XDP layer, from the rest of the netstack, and
assigning dedicated CPUs for this stage. The sysadm control/configure
the RX-CPU to NIC-RX queue (as usual) via procfs smp_affinity and how
many queues are configured via ethtool --set-channels. Benchmarks
show that a single CPU can handle approx 11Mpps. Thus, only assigning
two NIC RX-queues (and two CPUs) is sufficient for handling 10Gbit/s
wirespeed smallest packet 14.88Mpps. Reducing the number of queues
have the advantage that more packets being "bulk" available per hard
interrupt[1].
[1] https://www.netdevconf.org/2.1/papers/BusyPollingNextGen.pdf
Use-cases:
1. End-host based pre-filtering for DDoS mitigation. This is fast
enough to allow software to see and filter all packets wirespeed.
Thus, no packets getting silently dropped by hardware.
2. Given NIC HW unevenly distributes packets across RX queue, this
mechanism can be used for redistribution load across CPUs. This
usually happens when HW is unaware of a new protocol. This
resembles RPS (Receive Packet Steering), just faster, but with more
responsibility placed on the BPF program for correct steering.
3. Auto-scaling or power saving via only activating the appropriate
number of remote CPUs for handling the current load. The cpumap
tracepoints can function as a feedback loop for this purpose.
See individual patches for patchset-version changes.
Patchset V4 based on net-next at:
commit 26873308b216 ("Merge branch 'sctp-stream-schedulers'")
---
Jesper Dangaard Brouer (5):
bpf: introduce new bpf cpu map type BPF_MAP_TYPE_CPUMAP
bpf: XDP_REDIRECT enable use of cpumap
bpf: cpumap xdp_buff to skb conversion and allocation
bpf: cpumap add tracepoints
samples/bpf: add cpumap sample program xdp_redirect_cpu
include/linux/bpf.h | 31 ++
include/linux/bpf_types.h | 1
include/linux/netdevice.h | 1
include/trace/events/xdp.h | 80 ++++
include/uapi/linux/bpf.h | 1
kernel/bpf/Makefile | 1
kernel/bpf/cpumap.c | 674 +++++++++++++++++++++++++++++++++++
kernel/bpf/syscall.c | 8
kernel/bpf/verifier.c | 3
net/core/dev.c | 22 +
net/core/filter.c | 142 ++++++-
samples/bpf/Makefile | 4
samples/bpf/xdp_redirect_cpu_kern.c | 616 ++++++++++++++++++++++++++++++++
samples/bpf/xdp_redirect_cpu_user.c | 653 ++++++++++++++++++++++++++++++++++
tools/include/uapi/linux/bpf.h | 1
15 files changed, 2203 insertions(+), 35 deletions(-)
create mode 100644 kernel/bpf/cpumap.c
create mode 100644 samples/bpf/xdp_redirect_cpu_kern.c
create mode 100644 samples/bpf/xdp_redirect_cpu_user.c
^ permalink raw reply
* [net-next V4 PATCH 2/5] bpf: XDP_REDIRECT enable use of cpumap
From: Jesper Dangaard Brouer @ 2017-10-04 12:03 UTC (permalink / raw)
To: netdev
Cc: jakub.kicinski, Michael S. Tsirkin, pavel.odintsov, Jason Wang,
mchan, John Fastabend, peter.waskiewicz.jr,
Jesper Dangaard Brouer, Daniel Borkmann, Alexei Starovoitov,
Andy Gospodarek
In-Reply-To: <150711858281.9499.7767364427831352921.stgit@firesoul>
This patch connects cpumap to the xdp_do_redirect_map infrastructure.
Still no SKB allocation are done yet. The XDP frames are transferred
to the other CPU, but they are simply refcnt decremented on the remote
CPU. This served as a good benchmark for measuring the overhead of
remote refcnt decrement. If driver page recycle cache is not
efficient then this, exposes a bottleneck in the page allocator.
A shout-out to MST's ptr_ring, which is the secret behind is being so
efficient to transfer memory pointers between CPUs, without constantly
bouncing cache-lines between CPUs.
V3: Handle !CONFIG_BPF_SYSCALL pointed out by kbuild test robot.
V4: Make Generic-XDP aware of cpumap type, but don't allow redirect yet,
as implementation require a separate upstream discussion.
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
---
include/linux/bpf.h | 31 +++++++++-
include/trace/events/xdp.h | 10 ++-
kernel/bpf/cpumap.c | 5 +-
kernel/bpf/verifier.c | 3 +
net/core/filter.c | 142 +++++++++++++++++++++++++++++++++++---------
5 files changed, 155 insertions(+), 36 deletions(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 252f4bc9eb25..36ec83343c82 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -320,6 +320,13 @@ struct net_device *__dev_map_lookup_elem(struct bpf_map *map, u32 key);
void __dev_map_insert_ctx(struct bpf_map *map, u32 index);
void __dev_map_flush(struct bpf_map *map);
+struct bpf_cpu_map_entry *__cpu_map_lookup_elem(struct bpf_map *map, u32 key);
+void __cpu_map_insert_ctx(struct bpf_map *map, u32 index);
+void __cpu_map_flush(struct bpf_map *map);
+struct xdp_buff;
+int cpu_map_enqueue(struct bpf_cpu_map_entry *rcpu, struct xdp_buff *xdp,
+ struct net_device *dev_rx);
+
/* Return map's numa specified by userspace */
static inline int bpf_map_attr_numa_node(const union bpf_attr *attr)
{
@@ -327,7 +334,7 @@ static inline int bpf_map_attr_numa_node(const union bpf_attr *attr)
attr->numa_node : NUMA_NO_NODE;
}
-#else
+#else /* !CONFIG_BPF_SYSCALL */
static inline struct bpf_prog *bpf_prog_get(u32 ufd)
{
return ERR_PTR(-EOPNOTSUPP);
@@ -385,6 +392,28 @@ static inline void __dev_map_insert_ctx(struct bpf_map *map, u32 index)
static inline void __dev_map_flush(struct bpf_map *map)
{
}
+
+static inline
+struct bpf_cpu_map_entry *__cpu_map_lookup_elem(struct bpf_map *map, u32 key)
+{
+ return NULL;
+}
+
+static inline void __cpu_map_insert_ctx(struct bpf_map *map, u32 index)
+{
+}
+
+static inline void __cpu_map_flush(struct bpf_map *map)
+{
+}
+
+struct xdp_buff;
+static inline int cpu_map_enqueue(struct bpf_cpu_map_entry *rcpu,
+ struct xdp_buff *xdp,
+ struct net_device *dev_rx)
+{
+ return 0;
+}
#endif /* CONFIG_BPF_SYSCALL */
#if defined(CONFIG_STREAM_PARSER) && defined(CONFIG_BPF_SYSCALL)
diff --git a/include/trace/events/xdp.h b/include/trace/events/xdp.h
index 4e16c43fba10..eb2ece96c1a2 100644
--- a/include/trace/events/xdp.h
+++ b/include/trace/events/xdp.h
@@ -136,12 +136,18 @@ DEFINE_EVENT_PRINT(xdp_redirect_template, xdp_redirect_map_err,
__entry->map_id, __entry->map_index)
);
+#define devmap_ifindex(fwd, map) \
+ (!fwd ? 0 : \
+ (!map ? 0 : \
+ ((map->map_type == BPF_MAP_TYPE_DEVMAP) ? \
+ ((struct net_device *)fwd)->ifindex : 0)))
+
#define _trace_xdp_redirect_map(dev, xdp, fwd, map, idx) \
- trace_xdp_redirect_map(dev, xdp, fwd ? fwd->ifindex : 0, \
+ trace_xdp_redirect_map(dev, xdp, devmap_ifindex(fwd, map), \
0, map, idx)
#define _trace_xdp_redirect_map_err(dev, xdp, fwd, map, idx, err) \
- trace_xdp_redirect_map_err(dev, xdp, fwd ? fwd->ifindex : 0, \
+ trace_xdp_redirect_map_err(dev, xdp, devmap_ifindex(fwd, map), \
err, map, idx)
#endif /* _TRACE_XDP_H */
diff --git a/kernel/bpf/cpumap.c b/kernel/bpf/cpumap.c
index ae8e29352261..4926a9971f90 100644
--- a/kernel/bpf/cpumap.c
+++ b/kernel/bpf/cpumap.c
@@ -493,7 +493,8 @@ static int bq_enqueue(struct bpf_cpu_map_entry *rcpu, struct xdp_pkt *xdp_pkt)
return 0;
}
-int cpu_map_enqueue(struct bpf_cpu_map_entry *rcpu, struct xdp_buff *xdp)
+int cpu_map_enqueue(struct bpf_cpu_map_entry *rcpu, struct xdp_buff *xdp,
+ struct net_device *dev_rx)
{
struct xdp_pkt *xdp_pkt;
int headroom;
@@ -505,7 +506,7 @@ int cpu_map_enqueue(struct bpf_cpu_map_entry *rcpu, struct xdp_buff *xdp)
xdp_pkt = xdp->data_hard_start;
xdp_pkt->data = xdp->data;
xdp_pkt->len = xdp->data_end - xdp->data;
- xdp_pkt->headroom = headroom;
+ xdp_pkt->headroom = headroom - sizeof(*xdp_pkt);
/* For now this is just used as a void pointer to data_hard_start */
bq_enqueue(rcpu, xdp_pkt);
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 4cf9b72c59a0..670868f1b017 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -1608,7 +1608,8 @@ static int check_map_func_compatibility(struct bpf_map *map, int func_id)
goto error;
break;
case BPF_FUNC_redirect_map:
- if (map->map_type != BPF_MAP_TYPE_DEVMAP)
+ if (map->map_type != BPF_MAP_TYPE_DEVMAP &&
+ map->map_type != BPF_MAP_TYPE_CPUMAP)
goto error;
break;
case BPF_FUNC_sk_redirect_map:
diff --git a/net/core/filter.c b/net/core/filter.c
index 9b6e7e84aafd..dbf2ae071108 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -2521,10 +2521,36 @@ static int __bpf_tx_xdp(struct net_device *dev,
err = dev->netdev_ops->ndo_xdp_xmit(dev, xdp);
if (err)
return err;
- if (map)
+ dev->netdev_ops->ndo_xdp_flush(dev);
+ return 0;
+}
+
+static int __bpf_tx_xdp_map(struct net_device *dev_rx, void *fwd,
+ struct bpf_map *map,
+ struct xdp_buff *xdp,
+ u32 index)
+{
+ int err;
+
+ if (map->map_type == BPF_MAP_TYPE_DEVMAP) {
+ struct net_device *dev = fwd;
+
+ if (!dev->netdev_ops->ndo_xdp_xmit)
+ return -EOPNOTSUPP;
+
+ err = dev->netdev_ops->ndo_xdp_xmit(dev, xdp);
+ if (err)
+ return err;
__dev_map_insert_ctx(map, index);
- else
- dev->netdev_ops->ndo_xdp_flush(dev);
+
+ } else if (map->map_type == BPF_MAP_TYPE_CPUMAP) {
+ struct bpf_cpu_map_entry *rcpu = fwd;
+
+ err = cpu_map_enqueue(rcpu, xdp, dev_rx);
+ if (err)
+ return err;
+ __cpu_map_insert_ctx(map, index);
+ }
return 0;
}
@@ -2534,11 +2560,33 @@ void xdp_do_flush_map(void)
struct bpf_map *map = ri->map_to_flush;
ri->map_to_flush = NULL;
- if (map)
- __dev_map_flush(map);
+ if (map) {
+ switch (map->map_type) {
+ case BPF_MAP_TYPE_DEVMAP:
+ __dev_map_flush(map);
+ break;
+ case BPF_MAP_TYPE_CPUMAP:
+ __cpu_map_flush(map);
+ break;
+ default:
+ break;
+ }
+ }
}
EXPORT_SYMBOL_GPL(xdp_do_flush_map);
+static void *__xdp_map_lookup_elem(struct bpf_map *map, u32 index)
+{
+ switch (map->map_type) {
+ case BPF_MAP_TYPE_DEVMAP:
+ return __dev_map_lookup_elem(map, index);
+ case BPF_MAP_TYPE_CPUMAP:
+ return __cpu_map_lookup_elem(map, index);
+ default:
+ return NULL;
+ }
+}
+
static inline bool xdp_map_invalid(const struct bpf_prog *xdp_prog,
unsigned long aux)
{
@@ -2551,8 +2599,8 @@ static int xdp_do_redirect_map(struct net_device *dev, struct xdp_buff *xdp,
struct redirect_info *ri = this_cpu_ptr(&redirect_info);
unsigned long map_owner = ri->map_owner;
struct bpf_map *map = ri->map;
- struct net_device *fwd = NULL;
u32 index = ri->ifindex;
+ void *fwd = NULL;
int err;
ri->ifindex = 0;
@@ -2565,7 +2613,7 @@ static int xdp_do_redirect_map(struct net_device *dev, struct xdp_buff *xdp,
goto err;
}
- fwd = __dev_map_lookup_elem(map, index);
+ fwd = __xdp_map_lookup_elem(map, index);
if (!fwd) {
err = -EINVAL;
goto err;
@@ -2573,7 +2621,7 @@ static int xdp_do_redirect_map(struct net_device *dev, struct xdp_buff *xdp,
if (ri->map_to_flush && ri->map_to_flush != map)
xdp_do_flush_map();
- err = __bpf_tx_xdp(fwd, map, xdp, index);
+ err = __bpf_tx_xdp_map(dev, fwd, map, xdp, index);
if (unlikely(err))
goto err;
@@ -2615,54 +2663,88 @@ int xdp_do_redirect(struct net_device *dev, struct xdp_buff *xdp,
}
EXPORT_SYMBOL_GPL(xdp_do_redirect);
-int xdp_do_generic_redirect(struct net_device *dev, struct sk_buff *skb,
- struct bpf_prog *xdp_prog)
+static int __xdp_generic_ok_fwd_dev(struct sk_buff *skb, struct net_device *fwd)
+{
+ unsigned int len;
+
+ if (unlikely(!(fwd->flags & IFF_UP)))
+ return -ENETDOWN;
+
+ len = fwd->mtu + fwd->hard_header_len + VLAN_HLEN;
+ if (skb->len > len)
+ return -EMSGSIZE;
+
+ return 0;
+}
+
+int xdp_do_generic_redirect_map(struct net_device *dev, struct sk_buff *skb,
+ struct bpf_prog *xdp_prog)
{
struct redirect_info *ri = this_cpu_ptr(&redirect_info);
unsigned long map_owner = ri->map_owner;
struct bpf_map *map = ri->map;
- struct net_device *fwd = NULL;
u32 index = ri->ifindex;
- unsigned int len;
+ struct net_device *fwd;
int err = 0;
ri->ifindex = 0;
ri->map = NULL;
ri->map_owner = 0;
- if (map) {
- if (unlikely(xdp_map_invalid(xdp_prog, map_owner))) {
- err = -EFAULT;
- map = NULL;
- goto err;
- }
- fwd = __dev_map_lookup_elem(map, index);
- } else {
- fwd = dev_get_by_index_rcu(dev_net(dev), index);
+ if (unlikely(xdp_map_invalid(xdp_prog, map_owner))) {
+ err = -EFAULT;
+ map = NULL;
+ goto err;
}
+ fwd = __xdp_map_lookup_elem(map, index);
if (unlikely(!fwd)) {
err = -EINVAL;
goto err;
}
- if (unlikely(!(fwd->flags & IFF_UP))) {
- err = -ENETDOWN;
+ if (map->map_type == BPF_MAP_TYPE_DEVMAP) {
+ if (unlikely((err = __xdp_generic_ok_fwd_dev(skb, fwd))))
+ goto err;
+ skb->dev = fwd;
+ } else {
+ /* TODO: Handle BPF_MAP_TYPE_CPUMAP */
+ err = -EBADRQC;
goto err;
}
- len = fwd->mtu + fwd->hard_header_len + VLAN_HLEN;
- if (skb->len > len) {
- err = -EMSGSIZE;
+ _trace_xdp_redirect_map(dev, xdp_prog, fwd, map, index);
+ return 0;
+err:
+ _trace_xdp_redirect_map_err(dev, xdp_prog, fwd, map, index, err);
+ return err;
+}
+
+int xdp_do_generic_redirect(struct net_device *dev, struct sk_buff *skb,
+ struct bpf_prog *xdp_prog)
+{
+ struct redirect_info *ri = this_cpu_ptr(&redirect_info);
+ u32 index = ri->ifindex;
+ struct net_device *fwd;
+ int err = 0;
+
+ if (ri->map)
+ return xdp_do_generic_redirect_map(dev, skb, xdp_prog);
+
+ ri->ifindex = 0;
+ fwd = dev_get_by_index_rcu(dev_net(dev), index);
+ if (unlikely(!fwd)) {
+ err = -EINVAL;
goto err;
}
+ if (unlikely((err = __xdp_generic_ok_fwd_dev(skb, fwd))))
+ goto err;
+
skb->dev = fwd;
- map ? _trace_xdp_redirect_map(dev, xdp_prog, fwd, map, index)
- : _trace_xdp_redirect(dev, xdp_prog, index);
+ _trace_xdp_redirect(dev, xdp_prog, index);
return 0;
err:
- map ? _trace_xdp_redirect_map_err(dev, xdp_prog, fwd, map, index, err)
- : _trace_xdp_redirect_err(dev, xdp_prog, index, err);
+ _trace_xdp_redirect_err(dev, xdp_prog, index, err);
return err;
}
EXPORT_SYMBOL_GPL(xdp_do_generic_redirect);
^ permalink raw reply related
* [net-next V4 PATCH 3/5] bpf: cpumap xdp_buff to skb conversion and allocation
From: Jesper Dangaard Brouer @ 2017-10-04 12:03 UTC (permalink / raw)
To: netdev
Cc: jakub.kicinski, Michael S. Tsirkin, pavel.odintsov, Jason Wang,
mchan, John Fastabend, peter.waskiewicz.jr,
Jesper Dangaard Brouer, Daniel Borkmann, Alexei Starovoitov,
Andy Gospodarek
In-Reply-To: <150711858281.9499.7767364427831352921.stgit@firesoul>
This patch makes cpumap functional, by adding SKB allocation and
invoking the network stack on the dequeuing CPU.
For constructing the SKB on the remote CPU, the xdp_buff in converted
into a struct xdp_pkt, and it mapped into the top headroom of the
packet, to avoid allocating separate mem. For now, struct xdp_pkt is
just a cpumap internal data structure, with info carried between
enqueue to dequeue.
If a driver doesn't have enough headroom it is simply dropped, with
return code -EOVERFLOW. This will be picked up the xdp tracepoint
infrastructure, to allow users to catch this.
V2: take into account xdp->data_meta
V4:
- Drop busypoll tricks, keeping it more simple.
- Skip RPS and Generic-XDP-recursive-reinjection, suggested by Alexei
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
---
include/linux/netdevice.h | 1
kernel/bpf/cpumap.c | 150 +++++++++++++++++++++++++++++++++++++++------
net/core/dev.c | 22 +++++++
3 files changed, 152 insertions(+), 21 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index d04424cfffba..0a3dc246f066 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3251,6 +3251,7 @@ int do_xdp_generic(struct bpf_prog *xdp_prog, struct sk_buff *skb);
int netif_rx(struct sk_buff *skb);
int netif_rx_ni(struct sk_buff *skb);
int netif_receive_skb(struct sk_buff *skb);
+int netif_receive_skb_core(struct sk_buff *skb);
gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb);
void napi_gro_flush(struct napi_struct *napi, bool flush_old);
struct sk_buff *napi_get_frags(struct napi_struct *napi);
diff --git a/kernel/bpf/cpumap.c b/kernel/bpf/cpumap.c
index 4926a9971f90..4383d524432f 100644
--- a/kernel/bpf/cpumap.c
+++ b/kernel/bpf/cpumap.c
@@ -24,6 +24,9 @@
#include <linux/workqueue.h>
#include <linux/kthread.h>
+#include <linux/netdevice.h> /* netif_receive_skb_core */
+#include <linux/etherdevice.h> /* eth_type_trans */
+
/* General idea: XDP packets getting XDP redirected to another CPU,
* will maximum be stored/queued for one driver ->poll() call. It is
* guaranteed that setting flush bit and flush operation happen on
@@ -163,20 +166,136 @@ static void cpu_map_kthread_stop(struct work_struct *work)
kthread_stop(rcpu->kthread); /* calls put_cpu_map_entry */
}
+/* For now, xdp_pkt is a cpumap internal data structure, with info
+ * carried between enqueue to dequeue. It is mapped into the top
+ * headroom of the packet, to avoid allocating separate mem.
+ */
+struct xdp_pkt {
+ void *data;
+ u16 len;
+ u16 headroom;
+ u16 metasize;
+ struct net_device *dev_rx;
+};
+
+/* Convert xdp_buff to xdp_pkt */
+static struct xdp_pkt *convert_to_xdp_pkt(struct xdp_buff *xdp)
+{
+ struct xdp_pkt *xdp_pkt;
+ int metasize;
+ int headroom;
+
+ /* Assure headroom is available for storing info */
+ headroom = xdp->data - xdp->data_hard_start;
+ metasize = xdp->data - xdp->data_meta;
+ metasize = metasize > 0 ? metasize : 0;
+ if ((headroom - metasize) < sizeof(*xdp_pkt))
+ return NULL;
+
+ /* Store info in top of packet */
+ xdp_pkt = xdp->data_hard_start;
+
+ xdp_pkt->data = xdp->data;
+ xdp_pkt->len = xdp->data_end - xdp->data;
+ xdp_pkt->headroom = headroom - sizeof(*xdp_pkt);
+ xdp_pkt->metasize = metasize;
+
+ return xdp_pkt;
+}
+
+struct sk_buff *cpu_map_build_skb(struct bpf_cpu_map_entry *rcpu,
+ struct xdp_pkt *xdp_pkt)
+{
+ unsigned int frame_size;
+ void *pkt_data_start;
+ struct sk_buff *skb;
+
+ /* build_skb need to place skb_shared_info after SKB end, and
+ * also want to know the memory "truesize". Thus, need to
+ * know the memory frame size backing xdp_buff.
+ *
+ * XDP was designed to have PAGE_SIZE frames, but this
+ * assumption is not longer true with ixgbe and i40e. It
+ * would be preferred to set frame_size to 2048 or 4096
+ * depending on the driver.
+ * frame_size = 2048;
+ * frame_len = frame_size - sizeof(*xdp_pkt);
+ *
+ * Instead, with info avail, skb_shared_info in placed after
+ * packet len. This, unfortunately fakes the truesize.
+ * Another disadvantage of this approach, the skb_shared_info
+ * is not at a fixed memory location, with mixed length
+ * packets, which is bad for cache-line hotness.
+ */
+ frame_size = SKB_DATA_ALIGN(xdp_pkt->len) + xdp_pkt->headroom +
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+
+ pkt_data_start = xdp_pkt->data - xdp_pkt->headroom;
+ skb = build_skb(pkt_data_start, frame_size);
+ if (!skb)
+ return NULL;
+
+ skb_reserve(skb, xdp_pkt->headroom);
+ __skb_put(skb, xdp_pkt->len);
+ if (xdp_pkt->metasize)
+ skb_metadata_set(skb, xdp_pkt->metasize);
+
+ /* Essential SKB info: protocol and skb->dev */
+ skb->protocol = eth_type_trans(skb, xdp_pkt->dev_rx);
+
+ /* Optional SKB info, currently missing:
+ * - HW checksum info (skb->ip_summed)
+ * - HW RX hash (skb_set_hash)
+ * - RX ring dev queue index (skb_record_rx_queue)
+ */
+
+ return skb;
+}
+
static int cpu_map_kthread_run(void *data)
{
struct bpf_cpu_map_entry *rcpu = data;
set_current_state(TASK_INTERRUPTIBLE);
while (!kthread_should_stop()) {
+ unsigned int processed = 0, drops = 0;
struct xdp_pkt *xdp_pkt;
- schedule();
- /* Do work */
- while ((xdp_pkt = ptr_ring_consume(rcpu->queue))) {
- /* For now just "refcnt-free" */
- page_frag_free(xdp_pkt);
+ /* Release CPU reschedule checks */
+ if (__ptr_ring_empty(rcpu->queue)) {
+ schedule();
+ } else {
+ cond_resched();
+ }
+
+ /* Process packets in rcpu->queue */
+ local_bh_disable();
+ /*
+ * The bpf_cpu_map_entry is single consumer, with this
+ * kthread CPU pinned. Lockless access to ptr_ring
+ * consume side valid as no-resize allowed of queue.
+ */
+ while ((xdp_pkt = __ptr_ring_consume(rcpu->queue))) {
+ struct sk_buff *skb;
+ int ret;
+
+ skb = cpu_map_build_skb(rcpu, xdp_pkt);
+ if (!skb) {
+ page_frag_free(xdp_pkt);
+ continue;
+ }
+
+ /* Inject into network stack */
+ ret = netif_receive_skb_core(skb);
+ if (ret == NET_RX_DROP)
+ drops++;
+
+ /* Limit BH-disable period */
+ if (++processed == 8)
+ break;
}
+ local_bh_enable(); /* resched point, may call do_softirq() */
+
__set_current_state(TASK_INTERRUPTIBLE);
}
put_cpu_map_entry(rcpu);
@@ -463,13 +582,6 @@ static int bq_flush_to_queue(struct bpf_cpu_map_entry *rcpu,
return 0;
}
-/* Notice: Will change in later patch */
-struct xdp_pkt {
- void *data;
- u16 len;
- u16 headroom;
-};
-
/* Runs under RCU-read-side, plus in softirq under NAPI protection.
* Thus, safe percpu variable access.
*/
@@ -497,17 +609,13 @@ int cpu_map_enqueue(struct bpf_cpu_map_entry *rcpu, struct xdp_buff *xdp,
struct net_device *dev_rx)
{
struct xdp_pkt *xdp_pkt;
- int headroom;
- /* Convert xdp_buff to xdp_pkt */
- headroom = xdp->data - xdp->data_hard_start;
- if (headroom < sizeof(*xdp_pkt))
+ xdp_pkt = convert_to_xdp_pkt(xdp);
+ if (!xdp_pkt)
return -EOVERFLOW;
- xdp_pkt = xdp->data_hard_start;
- xdp_pkt->data = xdp->data;
- xdp_pkt->len = xdp->data_end - xdp->data;
- xdp_pkt->headroom = headroom - sizeof(*xdp_pkt);
- /* For now this is just used as a void pointer to data_hard_start */
+
+ /* Info needed when constructing SKB on remote CPU */
+ xdp_pkt->dev_rx = dev_rx;
bq_enqueue(rcpu, xdp_pkt);
return 0;
diff --git a/net/core/dev.c b/net/core/dev.c
index 1770097cfd86..3115828220aa 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4489,6 +4489,28 @@ static int __netif_receive_skb_core(struct sk_buff *skb, bool pfmemalloc)
return ret;
}
+/**
+ * netif_receive_skb_core - special purpose version of netif_receive_skb
+ * @skb: buffer to process
+ *
+ * More direct receive version of netif_receive_skb(). It should
+ * only be used by callers that have a need to skip RPS and Generic XDP.
+ * Caller must also take care of handling if (page_is_)pfmemalloc.
+ *
+ * This function may only be called from softirq context and interrupts
+ * should be enabled.
+ *
+ * Return values (usually ignored):
+ * NET_RX_SUCCESS: no congestion
+ * NET_RX_DROP: packet was dropped
+ */
+
+int netif_receive_skb_core(struct sk_buff *skb)
+{
+ return __netif_receive_skb_core(skb, false);
+}
+EXPORT_SYMBOL(netif_receive_skb_core);
+
static int __netif_receive_skb(struct sk_buff *skb)
{
int ret;
^ permalink raw reply related
* [net-next V4 PATCH 4/5] bpf: cpumap add tracepoints
From: Jesper Dangaard Brouer @ 2017-10-04 12:04 UTC (permalink / raw)
To: netdev
Cc: jakub.kicinski, Michael S. Tsirkin, pavel.odintsov, Jason Wang,
mchan, John Fastabend, peter.waskiewicz.jr,
Jesper Dangaard Brouer, Daniel Borkmann, Alexei Starovoitov,
Andy Gospodarek
In-Reply-To: <150711858281.9499.7767364427831352921.stgit@firesoul>
This adds two tracepoint to the cpumap. One for the enqueue side
trace_xdp_cpumap_enqueue() and one for the kthread dequeue side
trace_xdp_cpumap_kthread().
To mitigate the tracepoint overhead, these are invoked during the
enqueue/dequeue bulking phases, thus amortizing the cost.
The obvious use-cases are for debugging and monitoring. The
non-intuitive use-case is using these as a feedback loop to know the
system load. One can imagine auto-scaling by reducing, adding or
activating more worker CPUs on demand.
V4: tracepoint remove time_limit info, instead add sched info
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
---
include/trace/events/xdp.h | 70 ++++++++++++++++++++++++++++++++++++++++++++
kernel/bpf/cpumap.c | 23 +++++++++++---
2 files changed, 88 insertions(+), 5 deletions(-)
diff --git a/include/trace/events/xdp.h b/include/trace/events/xdp.h
index eb2ece96c1a2..0c8dec61987e 100644
--- a/include/trace/events/xdp.h
+++ b/include/trace/events/xdp.h
@@ -150,6 +150,76 @@ DEFINE_EVENT_PRINT(xdp_redirect_template, xdp_redirect_map_err,
trace_xdp_redirect_map_err(dev, xdp, devmap_ifindex(fwd, map), \
err, map, idx)
+TRACE_EVENT(xdp_cpumap_kthread,
+
+ TP_PROTO(int map_id, unsigned int processed, unsigned int drops,
+ int sched),
+
+ TP_ARGS(map_id, processed, drops, sched),
+
+ TP_STRUCT__entry(
+ __field(int, map_id)
+ __field(u32, act)
+ __field(int, cpu)
+ __field(unsigned int, drops)
+ __field(unsigned int, processed)
+ __field(int, sched)
+ ),
+
+ TP_fast_assign(
+ __entry->map_id = map_id;
+ __entry->act = XDP_REDIRECT;
+ __entry->cpu = smp_processor_id();
+ __entry->drops = drops;
+ __entry->processed = processed;
+ __entry->sched = sched;
+ ),
+
+ TP_printk("kthread"
+ " cpu=%d map_id=%d action=%s"
+ " processed=%u drops=%u"
+ " sched=%d",
+ __entry->cpu, __entry->map_id,
+ __print_symbolic(__entry->act, __XDP_ACT_SYM_TAB),
+ __entry->processed, __entry->drops,
+ __entry->sched)
+);
+
+TRACE_EVENT(xdp_cpumap_enqueue,
+
+ TP_PROTO(int map_id, unsigned int processed, unsigned int drops,
+ int to_cpu),
+
+ TP_ARGS(map_id, processed, drops, to_cpu),
+
+ TP_STRUCT__entry(
+ __field(int, map_id)
+ __field(u32, act)
+ __field(int, cpu)
+ __field(unsigned int, drops)
+ __field(unsigned int, processed)
+ __field(int, to_cpu)
+ ),
+
+ TP_fast_assign(
+ __entry->map_id = map_id;
+ __entry->act = XDP_REDIRECT;
+ __entry->cpu = smp_processor_id();
+ __entry->drops = drops;
+ __entry->processed = processed;
+ __entry->to_cpu = to_cpu;
+ ),
+
+ TP_printk("enqueue"
+ " cpu=%d map_id=%d action=%s"
+ " processed=%u drops=%u"
+ " to_cpu=%d",
+ __entry->cpu, __entry->map_id,
+ __print_symbolic(__entry->act, __XDP_ACT_SYM_TAB),
+ __entry->processed, __entry->drops,
+ __entry->to_cpu)
+);
+
#endif /* _TRACE_XDP_H */
#include <trace/define_trace.h>
diff --git a/kernel/bpf/cpumap.c b/kernel/bpf/cpumap.c
index 4383d524432f..571c668ac61b 100644
--- a/kernel/bpf/cpumap.c
+++ b/kernel/bpf/cpumap.c
@@ -23,6 +23,7 @@
#include <linux/sched.h>
#include <linux/workqueue.h>
#include <linux/kthread.h>
+#include <trace/events/xdp.h>
#include <linux/netdevice.h> /* netif_receive_skb_core */
#include <linux/etherdevice.h> /* eth_type_trans */
@@ -258,14 +259,15 @@ static int cpu_map_kthread_run(void *data)
set_current_state(TASK_INTERRUPTIBLE);
while (!kthread_should_stop()) {
- unsigned int processed = 0, drops = 0;
+ unsigned int processed = 0, drops = 0, sched = 0;
struct xdp_pkt *xdp_pkt;
/* Release CPU reschedule checks */
if (__ptr_ring_empty(rcpu->queue)) {
schedule();
+ sched = 1;
} else {
- cond_resched();
+ sched = cond_resched();
}
/* Process packets in rcpu->queue */
@@ -294,6 +296,9 @@ static int cpu_map_kthread_run(void *data)
if (++processed == 8)
break;
}
+ /* Feedback loop via tracepoint */
+ trace_xdp_cpumap_kthread(rcpu->map_id, processed, drops, sched);
+
local_bh_enable(); /* resched point, may call do_softirq() */
__set_current_state(TASK_INTERRUPTIBLE);
@@ -331,7 +336,10 @@ struct bpf_cpu_map_entry *__cpu_map_entry_alloc(u32 qsize, u32 cpu, int map_id)
err = ptr_ring_init(rcpu->queue, qsize, gfp);
if (err)
goto fail;
- rcpu->qsize = qsize;
+
+ rcpu->cpu = cpu;
+ rcpu->map_id = map_id;
+ rcpu->qsize = qsize;
/* Setup kthread */
rcpu->kthread = kthread_create_on_node(cpu_map_kthread_run, rcpu, numa,
@@ -557,6 +565,8 @@ const struct bpf_map_ops cpu_map_ops = {
static int bq_flush_to_queue(struct bpf_cpu_map_entry *rcpu,
struct xdp_bulk_queue *bq)
{
+ unsigned int processed = 0, drops = 0;
+ const int to_cpu = rcpu->cpu;
struct ptr_ring *q;
int i;
@@ -572,13 +582,16 @@ static int bq_flush_to_queue(struct bpf_cpu_map_entry *rcpu,
err = __ptr_ring_produce(q, xdp_pkt);
if (err) {
- /* Free xdp_pkt */
- page_frag_free(xdp_pkt);
+ drops++;
+ page_frag_free(xdp_pkt); /* Free xdp_pkt */
}
+ processed++;
}
bq->count = 0;
spin_unlock(&q->producer_lock);
+ /* Feedback loop via tracepoints */
+ trace_xdp_cpumap_enqueue(rcpu->map_id, processed, drops, to_cpu);
return 0;
}
^ permalink raw reply related
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