* Re: netfilter: xt_bpf: ABI issue in xt_bpf_info_v1?
From: Willem de Bruijn @ 2017-09-13 15:35 UTC (permalink / raw)
To: Jan Engelhardt
Cc: Shmulik Ladkani, netfilter-devel, Pablo Neira Ayuso,
Network Development, Willem de Bruijn, Rafael Buchbinder,
Shmulik Ladkani, eyal
In-Reply-To: <CAF=yD-LUCCLSXuPNKPgEY695ej+T-2s=zhmw6CJwK6tFyY+_dg@mail.gmail.com>
On Wed, Sep 13, 2017 at 11:05 AM, Willem de Bruijn
<willemdebruijn.kernel@gmail.com> wrote:
> On Wed, Sep 13, 2017 at 10:22 AM, Jan Engelhardt <jengelh@inai.de> wrote:
>>
>> On Wednesday 2017-09-13 15:24, Shmulik Ladkani wrote:
>>>
>>>One way to fix is to have iptables open the object (using the stored
>>>xt_bpf_info_v1->path), gaining a new process local fd for the object,
>>>just after getting the rules from IPT_SO_GET_ENTRIES.
>>>However we didn't see any other extensions doing something like that in
>>>iptables.
>
> The binary should call bpf_obj_get on the filepath each time. These are
> not regular files, but references to a pinned object in the bpf filesystem.
>
> Blindly passing back the fd received from the kernel is clearly wrong. I'm
> really surprised that I did not run into this problem when I wrote the
> feature.
>
>>>
>>>Another way to solve is to fix the ABI (or have a v2 one), that does NOT
>>>pass the fd from userspace, only the path of the pinned object.
>>>Then, 'bpf_mt_check_v1' will open the file from the given path in order
>>>to get the bpf_prog.
>>
>> But a path has a similar problem like a file descriptor - it is local to a
>> certain mount namespace.
>
> Because these are pinned objects in the bpf filesystem, and there is
> only one of those, it may be possible to lookup the object in the kernel
> without relying on a process-local view of mount points.
It would be preferable to fix this for the existing v1 users as well.
That said, the new bpf identifier feature allows passing a globally
unique id instead of a filepath.
>
>>
>> To load "large" blobs into the kernel, a pointer to user memory is a possible
>> option. The downside is that such extra data is not retrievable from the kernel
>> via the iptables setsockopts anymore - one could work around it with procfs, or
>> just let it be.
>>
>> https://sourceforge.net/p/xtables-addons/xtables-addons/ci/master/tree/extensions/xt_geoip.c
>> line 64+.
^ permalink raw reply
* Re: HTB going crazy over ~5Gbit/s (4.12.9, but problem present in older kernels as well)
From: Denys Fedoryshchenko @ 2017-09-13 15:34 UTC (permalink / raw)
To: Linux Kernel Network Developers
In-Reply-To: <4cd23914d8cc2cf5caf78cb5654fb245@nuclearcat.com>
Well, probably i am answering my own question, removing estimator from
classes seems drastically improve situation.
It seems estimator has some issues that cause shaper to behave
incorrectly (throttling traffic while it should not).
But i guess thats a bug?
As i was not able to predict such bottleneck by CPU load measurements.
On 2017-09-13 18:20, Denys Fedoryshchenko wrote:
> Hi,
>
> I noticed after increasing bandwidth over some amount HTB started to
> throttle classes it should not throttle.
> Also estimated rate in htb totally wrong, while byte counters is
> correct.
>
> Is there any overflow or something?
>
> X520 card (but XL710 same)
> br1 8000.90e2ba86c38c no eth3.1777
> eth3.777
> br2 8000.90e2ba86c38d no eth3.360
> eth3.361
>
> Inbound traffic is coming over one vlan, leaving another vlan.
> Shaper is just bunch of classes and u32 filters, with few fw filters.
> qdisc is pie
>
> I put totally high values to not reach them, tried to change
> quantum/burst/cburst but... stats below.
>
> First, "root" class is 1:1 showing rate 18086Mbit, which is
> physically impossible.
>
> Class 1:111 showing 5355Mbit, while real traffic is ~1.5Gbit
>
> shaper /etc # tc -s -d class show dev eth3.777 classid 1:111;sleep
> 5;tc -s -d class show dev eth3.777 classid 1:111
> class htb 1:111 parent 1:1 leaf 111: prio 0 quantum 50000 rate 10Gbit
> ceil 100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu
> 0b level 0
> Sent 6487632263 bytes 5235525 pkt (dropped 0, overlimits 0 requeues 0)
> rate 5529Mbit 557534pps backlog 0b 0p requeues 0
> lended: 2423323 borrowed: 0 giants: 0
> tokens: 124 ctokens: -1
>
> class htb 1:111 parent 1:1 leaf 111: prio 0 quantum 50000 rate 10Gbit
> ceil 100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu
> 0b level 0
> Sent 7438601731 bytes 6003811 pkt (dropped 0, overlimits 0 requeues 0)
> rate 5631Mbit 568214pps backlog 36624b 8p requeues 0
> lended: 2772486 borrowed: 0 giants: 0
> tokens: 124 ctokens: -1
>
> (7438601731-6487632263)/5*8 = 1.521.551.148
>
> And most important some classes suffering, while they should not (not
> reaching limits)
> class htb 1:95 parent 1:1 leaf 95: prio 0 quantum 50000 rate 10Gbit
> ceil 100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu
> 0b level 0
> Sent 13556762059 bytes 17474559 pkt (dropped 16017, overlimits 0
> requeues 0)
> rate 2524Mbit 414197pps backlog 31969245b 34513p requeues 0
> lended: 13995723 borrowed: 0 giants: 0
> tokens: 111 ctokens: -2
>
>
>
>
>
> Full classes stats:
>
> class htb 1:100 parent 1:1 leaf 100: prio 0 quantum 50000 rate 10Gbit
> ceil 100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu
> 0b level 0
> Sent 116 bytes 2 pkt (dropped 0, overlimits 0 requeues 0)
> rate 8bit 0pps backlog 0b 0p requeues 0
> lended: 2 borrowed: 0 giants: 0
> tokens: 124 ctokens: -1
>
> class htb 1:120 parent 1:1 leaf 120: prio 0 quantum 50000 rate 10Gbit
> ceil 100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu
> 0b level 0
> Sent 531230043 bytes 782130 pkt (dropped 0, overlimits 0 requeues 0)
> rate 132274Kbit 25240pps backlog 0b 0p requeues 0
> lended: 540693 borrowed: 0 giants: 0
> tokens: 109 ctokens: -2
>
> class htb 1:50 parent 1:1 leaf 50: prio 0 quantum 50000 rate 10Gbit
> ceil 100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu
> 0b level 0
> Sent 773472109 bytes 587335 pkt (dropped 0, overlimits 0 requeues 0)
> rate 215929Kbit 20503pps backlog 0b 0p requeues 0
> lended: 216614 borrowed: 0 giants: 0
> tokens: 91 ctokens: -4
>
> class htb 1:70 parent 1:1 leaf 70: prio 0 quantum 50000 rate 10Gbit
> ceil 100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu
> 0b level 0
> Sent 1574768 bytes 6194 pkt (dropped 0, overlimits 0 requeues 0)
> rate 406272bit 214pps backlog 0b 0p requeues 0
> lended: 5758 borrowed: 0 giants: 0
> tokens: 101 ctokens: -3
>
> class htb 1:90 parent 1:1 leaf 90: prio 0 quantum 50000 rate 1Kbit
> ceil 100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu
> 0b level 0
> Sent 3206 bytes 53 pkt (dropped 0, overlimits 0 requeues 0)
> rate 848bit 1pps backlog 0b 0p requeues 0
> lended: 53 borrowed: 0 giants: 0
>
> class htb 1:110 parent 1:1 leaf 110: prio 0 quantum 50000 rate 10Gbit
> ceil 100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu
> 0b level 0
> Sent 17205952113 bytes 12926008 pkt (dropped 239, overlimits 0
> requeues 0)
> rate 4433Mbit 416825pps backlog 5847785b 2394p requeues 0
> lended: 7021696 borrowed: 0 giants: 0
> tokens: 91 ctokens: -4
>
> class htb 1:45 root leaf 45: prio 0 quantum 50000 rate 80Mbit ceil
> 80Mbit linklayer ethernet burst 10000b/1 mpu 0b cburst 10000b/1 mpu 0b
> level 0
> Sent 2586 bytes 45 pkt (dropped 0, overlimits 0 requeues 0)
> rate 456bit 1pps backlog 0b 0p requeues 0
> lended: 45 borrowed: 0 giants: 0
> tokens: 15540 ctokens: 15540
>
> class htb 1:1 root rate 100Gbit ceil 100Gbit linklayer ethernet burst
> 0b/1 mpu 0b cburst 0b/1 mpu 0b level 7
> Sent 72277215121 bytes 72693012 pkt (dropped 0, overlimits 0 requeues
> 0)
> rate 18086Mbit 2304729pps backlog 0b 0p requeues 0
> lended: 0 borrowed: 0 giants: 0
> tokens: -4 ctokens: -4
>
> class htb 1:111 parent 1:1 leaf 111: prio 0 quantum 50000 rate 10Gbit
> ceil 100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu
> 0b level 0
> Sent 21977384237 bytes 17697345 pkt (dropped 391, overlimits 0
> requeues 0)
> rate 5355Mbit 543216pps backlog 41746345b 14743p requeues 0
> lended: 8837667 borrowed: 0 giants: 0
> tokens: 124 ctokens: -1
>
> class htb 1:200 parent 1:1 leaf 200: prio 0 quantum 50000 rate 10Gbit
> ceil 100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu
> 0b level 0
> Sent 9209112058 bytes 10941655 pkt (dropped 5396413, overlimits 0
> requeues 0)
> rate 2142Mbit 326938pps backlog 20798724b 25717p requeues 0
> lended: 9926866 borrowed: 0 giants: 0
> tokens: 108 ctokens: -2
>
> class htb 1:20 parent 1:1 leaf 20: prio 0 quantum 50000 rate 10Gbit
> ceil 100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu
> 0b level 0
> Sent 1504918577 bytes 1170037 pkt (dropped 0, overlimits 0 requeues 0)
> rate 413892Kbit 40322pps backlog 0b 0p requeues 0
> lended: 497069 borrowed: 0 giants: 0
> tokens: 92 ctokens: -4
>
> class htb 1:40 parent 1:1 leaf 40: prio 0 quantum 50000 rate 1Gbit
> ceil 1Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 10000b/1
> mpu 0b level 0
> Sent 8638241052 bytes 9526035 pkt (dropped 0, overlimits 0 requeues 0)
> rate 2442Mbit 333804pps backlog 0b 0p requeues 0
> lended: 6947694 borrowed: 0 giants: 0
> tokens: 1064 ctokens: 1064
>
> class htb 1:60 parent 1:1 leaf 60: prio 0 quantum 50000 rate 10Gbit
> ceil 100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu
> 0b level 0
> Sent 3124889750 bytes 6972789 pkt (dropped 5833, overlimits 0 requeues
> 0)
> rate 824981Kbit 233296pps backlog 616b 3p requeues 0
> lended: 6701559 borrowed: 0 giants: 0
> tokens: 122 ctokens: -1
>
> class htb 1:25 parent 1:1 leaf 25: prio 0 quantum 50000 rate 10Gbit
> ceil 100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu
> 0b level 0
> Sent 3275 bytes 57 pkt (dropped 0, overlimits 0 requeues 0)
> rate 504bit 1pps backlog 0b 0p requeues 0
> lended: 57 borrowed: 0 giants: 0
> tokens: 123 ctokens: -1
>
> class htb 1:80 parent 1:1 leaf 80: prio 0 quantum 50000 rate 10Gbit
> ceil 100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu
> 0b level 0
> Sent 2598 bytes 45 pkt (dropped 0, overlimits 0 requeues 0)
> rate 672bit 1pps backlog 0b 0p requeues 0
> lended: 45 borrowed: 0 giants: 0
> tokens: 124 ctokens: -1
>
> tc -s -d qdisc show dev eth3.777
> qdisc htb 1: root refcnt 2 r2q 10 default 200 direct_packets_stat 6858
> ver 3.17 direct_qlen 1000
> Sent 185271955178 bytes 186767377 pkt (dropped 14248387, overlimits 0
> requeues 0)
> backlog 62369772b 68728p requeues 0
> qdisc pie 120: parent 1:120 limit 40000p target 200.0ms tupdate 30.0ms
> alpha 2 beta 20
> Sent 1532094051 bytes 2108158 pkt (dropped 0, overlimits 0 requeues 0)
> backlog 0b 0p requeues 0
> prob 0.000000 delay 0us avg_dq_rate 0
> pkts_in 1424069 overlimit 0 dropped 0 maxq 96 ecn_mark 0
>
> qdisc pie 95: parent 1:95 limit 40000p target 250.0ms tupdate 30.0ms
> alpha 2 beta 20
> Sent 24359099839 bytes 31531160 pkt (dropped 36527, overlimits 0
> requeues 0)
> backlog 27116831b 28680p requeues 0
> prob 0.000000 delay 82019us avg_dq_rate 96252441
> pkts_in 25249681 overlimit 2107 dropped 36527 maxq 39999 ecn_mark 0
>
> qdisc pie 80: parent 1:80 limit 40000p target 250.0ms tupdate 30.0ms
> alpha 2 beta 20
> Sent 19695 bytes 317 pkt (dropped 0, overlimits 0 requeues 0)
> backlog 0b 0p requeues 0
> prob 0.000000 delay 0us avg_dq_rate 0
> pkts_in 317 overlimit 0 dropped 0 maxq 1 ecn_mark 0
>
> qdisc pie 111: parent 1:111 limit 40000p target 200.0ms tupdate
> 300.0ms alpha 2 beta 20
> Sent 57513872600 bytes 46387754 pkt (dropped 0, overlimits 0 requeues
> 0)
> backlog 126218b 49p requeues 0
> prob 0.000000 delay 227us avg_dq_rate 184143066
>
> qdisc pie 100: parent 1:100 limit 40000p target 200.0ms tupdate 30.0ms
> alpha 2 beta 20
> Sent 494 bytes 9 pkt (dropped 0, overlimits 0 requeues 0)
> backlog 0b 0p requeues 0
> prob 0.000000 delay 0us avg_dq_rate 0
> pkts_in 9 overlimit 0 dropped 0 maxq 0 ecn_mark 0
>
> qdisc pie 60: parent 1:60 limit 40000p target 250.0ms tupdate 30.0ms
> alpha 2 beta 20
> Sent 8749993535 bytes 18718111 pkt (dropped 0, overlimits 0 requeues
> 0)
> backlog 7875b 14p requeues 0
> prob 0.000000 delay 98us avg_dq_rate 0
> pkts_in 17978754 overlimit 0 dropped 0 maxq 281 ecn_mark 0
>
> qdisc pie 25: parent 1:25 limit 40000p target 250.0ms tupdate 30.0ms
> alpha 2 beta 20
> Sent 9412 bytes 135 pkt (dropped 0, overlimits 0 requeues 0)
> backlog 0b 0p requeues 0
> prob 0.000000 delay 0us avg_dq_rate 0
> pkts_in 135 overlimit 0 dropped 0 maxq 0 ecn_mark 0
>
> qdisc pie 200: parent 1:200 limit 40000p target 50.0ms tupdate 30.0ms
> alpha 2 beta 20
> Sent 22224392951 bytes 26861660 pkt (dropped 14211817, overlimits 0
> requeues 0)
> backlog 35124441b 39999p requeues 0
> prob 0.000071 delay 23747us avg_dq_rate 66040039
> pkts_in 25266532 overlimit 14160730 dropped 14211817 maxq 39999
> ecn_mark
> 0
>
> qdisc pie 90: parent 1:90 limit 40000p target 250.0ms tupdate 30.0ms
> alpha 2 beta 20
> Sent 7396 bytes 134 pkt (dropped 0, overlimits 0 requeues 0)
> backlog 0b 0p requeues 0
> prob 0.000000 delay 0us avg_dq_rate 0
> pkts_in 134 overlimit 0 dropped 0 maxq 0 ecn_mark 0
>
> qdisc pie 40: parent 1:40 limit 40000p target 200.0ms tupdate 30.0ms
> alpha 2 beta 20
> Sent 21316494470 bytes 23786396 pkt (dropped 0, overlimits 0 requeues
> 0)
> backlog 0b 0p requeues 0
> prob 0.000000 delay 0us avg_dq_rate 2085892079
> pkts_in 17465291 overlimit 0 dropped 0 maxq 184 ecn_mark 0
>
> qdisc pie 110: parent 1:110 limit 40000p target 200.0ms tupdate
> 300.0ms alpha 2 beta 20
> Sent 44081304635 bytes 33108042 pkt (dropped 0, overlimits 0 requeues
> 0)
> backlog 0b 0p requeues 0
> prob 0.000000 delay 47us avg_dq_rate 201721191
> pkts_in 17602600 overlimit 0 dropped 0 maxq 157 ecn_mark 0
>
> qdisc pie 70: parent 1:70 limit 40000p target 250.0ms tupdate 30.0ms
> alpha 2 beta 20
> Sent 4992265 bytes 16959 pkt (dropped 0, overlimits 0 requeues 0)
> backlog 0b 0p requeues 0
> prob 0.000000 delay 0us avg_dq_rate 0
> pkts_in 15448 overlimit 0 dropped 0 maxq 3 ecn_mark 0
>
> qdisc pie 20: parent 1:20 limit 40000p target 250.0ms tupdate 30.0ms
> alpha 2 beta 20
> Sent 3475884019 bytes 2717342 pkt (dropped 0, overlimits 0 requeues 0)
> backlog 0b 0p requeues 0
> prob 0.000000 delay 0us avg_dq_rate 0
> pkts_in 1186311 overlimit 0 dropped 0 maxq 41 ecn_mark 0
>
> qdisc pie 50: parent 1:50 limit 40000p target 250.0ms tupdate 30.0ms
> alpha 2 beta 20 ecn
> Sent 1994354891 bytes 1511636 pkt (dropped 0, overlimits 0 requeues 0)
> backlog 0b 0p requeues 0
> prob 0.000000 delay 0us avg_dq_rate 0
> pkts_in 561648 overlimit 0 dropped 0 maxq 27 ecn_mark 0
>
>
>
> More info about setup:
> shaper /etc # ethtool -k eth3
> Features for eth3:
> rx-checksumming: on
> tx-checksumming: on
> tx-checksum-ipv4: off [fixed]
> tx-checksum-ip-generic: on
> tx-checksum-ipv6: off [fixed]
> tx-checksum-fcoe-crc: on [fixed]
> tx-checksum-sctp: on
> scatter-gather: on
> tx-scatter-gather: on
> tx-scatter-gather-fraglist: off [fixed]
> tcp-segmentation-offload: off
> tx-tcp-segmentation: off
> tx-tcp-ecn-segmentation: off [fixed]
> tx-tcp-mangleid-segmentation: off
> tx-tcp6-segmentation: off
> udp-fragmentation-offload: off [fixed]
> generic-segmentation-offload: on
> generic-receive-offload: on
> large-receive-offload: off
> rx-vlan-offload: on
> tx-vlan-offload: on
> ntuple-filters: off
> receive-hashing: on
> highdma: on [fixed]
> rx-vlan-filter: on
> vlan-challenged: off [fixed]
> tx-lockless: off [fixed]
> netns-local: off [fixed]
> tx-gso-robust: off [fixed]
> tx-fcoe-segmentation: on [fixed]
> tx-gre-segmentation: on
> tx-gre-csum-segmentation: on
> tx-ipxip4-segmentation: on
> tx-ipxip6-segmentation: on
> tx-udp_tnl-segmentation: on
> tx-udp_tnl-csum-segmentation: on
> rx-all: off
> tx-vlan-stag-hw-insert: off [fixed]
> rx-vlan-stag-hw-parse: off [fixed]
> rx-vlan-stag-filter: off [fixed]
> l2-fwd-offload: off
> hw-tc-offload: off
> esp-hw-offload: off [fixed]
> esp-tx-csum-hw-offload: off [fixed]
> shaper /etc # ethtool -k eth3.777
> Features for eth3.777:
> rx-checksumming: off [fixed]
> tx-checksumming: on
> tx-checksum-ipv4: off [fixed]
> tx-checksum-ip-generic: on
> tx-checksum-ipv6: off [fixed]
> tx-checksum-fcoe-crc: on
> tx-checksum-sctp: on
> scatter-gather: on
> tx-scatter-gather: on
> tx-scatter-gather-fraglist: off [requested on]
> tcp-segmentation-offload: off
> tx-tcp-segmentation: off
> tx-tcp-ecn-segmentation: off
> tx-tcp-mangleid-segmentation: off
> tx-tcp6-segmentation: off
> udp-fragmentation-offload: on
> generic-segmentation-offload: on
> generic-receive-offload: on
> large-receive-offload: off [fixed]
> rx-vlan-offload: off [fixed]
> tx-vlan-offload: off [fixed]
> ntuple-filters: off [fixed]
> receive-hashing: off [fixed]
> highdma: on
> rx-vlan-filter: off [fixed]
> vlan-challenged: off [fixed]
> tx-lockless: on [fixed]
> netns-local: off [fixed]
> tx-gso-robust: off [fixed]
> tx-fcoe-segmentation: on
> tx-gre-segmentation: off [fixed]
> tx-gre-csum-segmentation: off [fixed]
> tx-ipxip4-segmentation: off [fixed]
> tx-ipxip6-segmentation: off [fixed]
> tx-udp_tnl-segmentation: off [fixed]
> tx-udp_tnl-csum-segmentation: off [fixed]
> tx-gso-partial: off [fixed]
> tx-sctp-segmentation: on
> tx-esp-segmentation: off [fixed]
> fcoe-mtu: off [requested on]
> tx-nocache-copy: off
> loopback: off [fixed]
> rx-fcs: off [fixed]
> rx-all: off [fixed]
> tx-vlan-stag-hw-insert: off [fixed]
> rx-vlan-stag-hw-parse: off [fixed]
> rx-vlan-stag-filter: off [fixed]
> l2-fwd-offload: off [fixed]
> hw-tc-offload: off [fixed]
> esp-hw-offload: off [fixed]
> esp-tx-csum-hw-offload: off [fixed]
>
>
> shaper /etc # ethtool -i eth3
> driver: ixgbe
> version: 5.0.0-k
> firmware-version: 0x2b2c0001
> expansion-rom-version:
> bus-info: 0000:06:00.1
> supports-statistics: yes
> supports-test: yes
> supports-eeprom-access: yes
> supports-register-dump: yes
> supports-priv-flags: yes
>
> mpstat -P ALL 10
> Linux 4.12.9-build-0132 (shaper) 09/13/17 _x86_64_ (32 CPU)
>
> 18:15:55 CPU %usr %nice %sys %iowait %irq %soft
> %steal %guest %idle
> 18:16:05 all 0.00 0.00 0.00 0.00 0.00 0.63
> 0.00 0.00 99.37
> 18:16:05 0 0.00 0.00 0.13 0.00 0.00 0.13
> 0.00 0.00 99.73
> 18:16:05 1 0.00 0.00 0.00 0.00 0.00 1.34
> 0.00 0.00 98.66
> 18:16:05 2 0.00 0.00 0.00 0.00 0.00 1.32
> 0.00 0.00 98.68
> 18:16:05 3 0.00 0.00 0.00 0.00 0.00 1.81
> 0.00 0.00 98.19
> 18:16:05 4 0.00 0.00 0.00 0.00 0.00 1.78
> 0.00 0.00 98.22
> 18:16:05 5 0.00 0.00 0.00 0.00 0.00 1.77
> 0.00 0.00 98.23
> 18:16:05 6 0.00 0.00 0.00 0.00 0.00 1.77
> 0.00 0.00 98.23
> 18:16:05 7 0.00 0.00 0.00 0.00 0.00 0.00
> 0.00 0.00 100.00
> 18:16:05 8 0.00 0.00 0.00 0.00 0.00 0.15
> 0.00 0.00 99.85
> 18:16:05 9 0.00 0.00 0.00 0.00 0.00 0.00
> 0.00 0.00 100.00
> 18:16:05 10 0.00 0.00 0.00 0.00 0.00 0.15
> 0.00 0.00 99.85
> 18:16:05 11 0.00 0.00 0.00 0.00 0.00 0.00
> 0.00 0.00 100.00
> 18:16:05 12 0.00 0.00 0.00 0.00 0.00 0.48
> 0.00 0.00 99.52
> 18:16:05 13 0.00 0.00 0.00 0.00 0.00 0.59
> 0.00 0.00 99.41
> 18:16:05 14 0.00 0.00 0.00 0.00 0.00 1.30
> 0.00 0.00 98.70
> 18:16:05 15 0.00 0.00 0.00 0.00 0.00 0.00
> 0.00 0.00 100.00
> 18:16:05 16 0.00 0.00 0.00 0.00 0.00 0.12
> 0.00 0.00 99.88
> 18:16:05 17 0.00 0.00 0.00 0.00 0.00 0.82
> 0.00 0.00 99.18
> 18:16:05 18 0.00 0.00 0.00 0.00 0.00 0.71
> 0.00 0.00 99.29
> 18:16:05 19 0.00 0.00 0.00 0.00 0.00 0.71
> 0.00 0.00 99.29
> 18:16:05 20 0.00 0.00 0.00 0.00 0.00 0.72
> 0.00 0.00 99.28
> 18:16:05 21 0.00 0.00 0.00 0.00 0.00 0.59
> 0.00 0.00 99.41
> 18:16:05 22 0.00 0.00 0.00 0.00 0.00 1.30
> 0.00 0.00 98.70
> 18:16:05 23 0.00 0.00 0.00 0.00 0.00 1.18
> 0.00 0.00 98.82
> 18:16:05 24 0.00 0.00 0.00 0.00 0.00 0.00
> 0.00 0.00 100.00
> 18:16:05 25 0.00 0.00 0.00 0.00 0.00 0.84
> 0.00 0.00 99.16
> 18:16:05 26 0.00 0.00 0.00 0.00 0.00 0.00
> 0.00 0.00 100.00
> 18:16:05 27 0.00 0.00 0.00 0.00 0.00 0.85
> 0.00 0.00 99.15
> 18:16:05 28 0.00 0.00 0.00 0.00 0.00 0.00
> 0.00 0.00 100.00
> 18:16:05 29 0.00 0.00 0.12 0.00 0.00 0.12
> 0.00 0.00 99.76
> 18:16:05 30 0.00 0.00 0.00 0.00 0.00 0.00
> 0.00 0.00 100.00
> 18:16:05 31 0.00 0.00 0.00 0.00 0.00 0.00
> 0.00 0.00 100.00
^ permalink raw reply
* [patch net] net: sched: fix use-after-free in tcf_action_destroy and tcf_del_walker
From: Jiri Pirko @ 2017-09-13 15:32 UTC (permalink / raw)
To: netdev; +Cc: davem, jhs, xiyou.wangcong, kubakici, mlxsw
From: Jiri Pirko <jiri@mellanox.com>
Recent commit d7fb60b9cafb ("net_sched: get rid of tcfa_rcu") removed
freeing in call_rcu, which changed already existing hard-to-hit
race condition into 100% hit:
[ 598.599825] BUG: unable to handle kernel NULL pointer dereference at 0000000000000030
[ 598.607782] IP: tcf_action_destroy+0xc0/0x140
Or:
[ 40.858924] BUG: unable to handle kernel NULL pointer dereference at 0000000000000030
[ 40.862840] IP: tcf_generic_walker+0x534/0x820
Fix this by storing the ops and use them directly for module_put call.
Fixes: a85a970af265 ("net_sched: move tc_action into tcf_common")
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
net/sched/act_api.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index fcd7dc7..da6fa82 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -180,7 +180,7 @@ static int tcf_del_walker(struct tcf_idrinfo *idrinfo, struct sk_buff *skb,
idr_for_each_entry_ext(idr, p, id) {
ret = __tcf_idr_release(p, false, true);
if (ret == ACT_P_DELETED) {
- module_put(p->ops->owner);
+ module_put(ops->owner);
n_i++;
} else if (ret < 0) {
goto nla_put_failure;
@@ -514,13 +514,15 @@ EXPORT_SYMBOL(tcf_action_exec);
int tcf_action_destroy(struct list_head *actions, int bind)
{
+ const struct tc_action_ops *ops;
struct tc_action *a, *tmp;
int ret = 0;
list_for_each_entry_safe(a, tmp, actions, list) {
+ ops = a->ops;
ret = __tcf_idr_release(a, bind, true);
if (ret == ACT_P_DELETED)
- module_put(a->ops->owner);
+ module_put(ops->owner);
else if (ret < 0)
return ret;
}
--
2.9.3
^ permalink raw reply related
* [PATCH stable-3.16 3/3] VSOCK: Detach QP check should filter out non matching QPs.
From: Michal Hocko @ 2017-09-13 15:23 UTC (permalink / raw)
To: Jorgen S. Hansen
Cc: Aditya Sarwade, Thomas Hellstrom, Petr Masik, Ben Hutchings,
Sasha Levin, netdev, Stable tree, LKML
In-Reply-To: <20170913152307.20317-1-mhocko@kernel.org>
From: Jorgen Hansen <jhansen@vmware.com>
commit 8ab18d71de8b07d2c4d6f984b718418c09ea45c5 upstream.
The check in vmci_transport_peer_detach_cb should only allow a
detach when the qp handle of the transport matches the one in
the detach message.
Testing: Before this change, a detach from a peer on a different
socket would cause an active stream socket to register a detach.
Reviewed-by: George Zhang <georgezhang@vmware.com>
Signed-off-by: Jorgen Hansen <jhansen@vmware.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Michal Hocko <mhocko@suse.com>
---
net/vmw_vsock/vmci_transport.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
index 314312272e08..c69c990ec4a2 100644
--- a/net/vmw_vsock/vmci_transport.c
+++ b/net/vmw_vsock/vmci_transport.c
@@ -844,7 +844,7 @@ static void vmci_transport_peer_detach_cb(u32 sub_id,
* qp_handle.
*/
if (vmci_handle_is_invalid(e_payload->handle) ||
- vmci_handle_is_equal(trans->qp_handle, e_payload->handle))
+ !vmci_handle_is_equal(trans->qp_handle, e_payload->handle))
return;
/* We don't ask for delayed CBs when we subscribe to this event (we
@@ -2158,7 +2158,7 @@ module_exit(vmci_transport_exit);
MODULE_AUTHOR("VMware, Inc.");
MODULE_DESCRIPTION("VMCI transport for Virtual Sockets");
-MODULE_VERSION("1.0.2.0-k");
+MODULE_VERSION("1.0.3.0-k");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("vmware_vsock");
MODULE_ALIAS_NETPROTO(PF_VSOCK);
--
2.14.1
^ permalink raw reply related
* [PATCH stable-3.16 2/3] VSOCK: Fix lockdep issue.
From: Michal Hocko @ 2017-09-13 15:23 UTC (permalink / raw)
To: Jorgen S. Hansen
Cc: Aditya Sarwade, Thomas Hellstrom, Petr Masik, Ben Hutchings,
Sasha Levin, netdev, Stable tree, LKML
In-Reply-To: <20170913152307.20317-1-mhocko@kernel.org>
From: Jorgen Hansen <jhansen@vmware.com>
commit 8566b86ab9f0f45bc6f7dd422b21de9d0cf5415a upstream.
The recent fix for the vsock sock_put issue used the wrong
initializer for the transport spin_lock causing an issue when
running with lockdep checking.
Testing: Verified fix on kernel with lockdep enabled.
Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: Jorgen Hansen <jhansen@vmware.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Michal Hocko <mhocko@suse.com>
---
net/vmw_vsock/vmci_transport.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
index aed136d27b01..314312272e08 100644
--- a/net/vmw_vsock/vmci_transport.c
+++ b/net/vmw_vsock/vmci_transport.c
@@ -1570,7 +1570,7 @@ static int vmci_transport_socket_init(struct vsock_sock *vsk,
vmci_trans(vsk)->notify_ops = NULL;
INIT_LIST_HEAD(&vmci_trans(vsk)->elem);
vmci_trans(vsk)->sk = &vsk->sk;
- vmci_trans(vsk)->lock = __SPIN_LOCK_UNLOCKED(vmci_trans(vsk)->lock);
+ spin_lock_init(&vmci_trans(vsk)->lock);
if (psk) {
vmci_trans(vsk)->queue_pair_size =
vmci_trans(psk)->queue_pair_size;
--
2.14.1
^ permalink raw reply related
* [PATCH stable-3.16 1/3] VSOCK: sock_put wasn't safe to call in interrupt context
From: Michal Hocko @ 2017-09-13 15:23 UTC (permalink / raw)
To: Jorgen S. Hansen
Cc: Aditya Sarwade, Thomas Hellstrom, Petr Masik, Ben Hutchings,
Sasha Levin, netdev, Stable tree, LKML
In-Reply-To: <20170913151939.gf7n6rvvjtz47tz7@dhcp22.suse.cz>
From: Jorgen Hansen <jhansen@vmware.com>
commit 4ef7ea9195ea73262cd9730fb54e1eb726da157b upstream.
In the vsock vmci_transport driver, sock_put wasn't safe to call
in interrupt context, since that may call the vsock destructor
which in turn calls several functions that should only be called
from process context. This change defers the callling of these
functions to a worker thread. All these functions were
deallocation of resources related to the transport itself.
Furthermore, an unused callback was removed to simplify the
cleanup.
Multiple customers have been hitting this issue when using
VMware tools on vSphere 2015.
Also added a version to the vmci transport module (starting from
1.0.2.0-k since up until now it appears that this module was
sharing version with vsock that is currently at 1.0.1.0-k).
Reviewed-by: Aditya Asarwade <asarwade@vmware.com>
Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: Jorgen Hansen <jhansen@vmware.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Michal Hocko <mhocko@suse.com>
---
net/vmw_vsock/vmci_transport.c | 173 ++++++++++++++++++++---------------------
net/vmw_vsock/vmci_transport.h | 4 +-
2 files changed, 86 insertions(+), 91 deletions(-)
diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
index 9bb63ffec4f2..aed136d27b01 100644
--- a/net/vmw_vsock/vmci_transport.c
+++ b/net/vmw_vsock/vmci_transport.c
@@ -40,13 +40,11 @@
static int vmci_transport_recv_dgram_cb(void *data, struct vmci_datagram *dg);
static int vmci_transport_recv_stream_cb(void *data, struct vmci_datagram *dg);
-static void vmci_transport_peer_attach_cb(u32 sub_id,
- const struct vmci_event_data *ed,
- void *client_data);
static void vmci_transport_peer_detach_cb(u32 sub_id,
const struct vmci_event_data *ed,
void *client_data);
static void vmci_transport_recv_pkt_work(struct work_struct *work);
+static void vmci_transport_cleanup(struct work_struct *work);
static int vmci_transport_recv_listen(struct sock *sk,
struct vmci_transport_packet *pkt);
static int vmci_transport_recv_connecting_server(
@@ -75,6 +73,10 @@ struct vmci_transport_recv_pkt_info {
struct vmci_transport_packet pkt;
};
+static LIST_HEAD(vmci_transport_cleanup_list);
+static DEFINE_SPINLOCK(vmci_transport_cleanup_lock);
+static DECLARE_WORK(vmci_transport_cleanup_work, vmci_transport_cleanup);
+
static struct vmci_handle vmci_transport_stream_handle = { VMCI_INVALID_ID,
VMCI_INVALID_ID };
static u32 vmci_transport_qp_resumed_sub_id = VMCI_INVALID_ID;
@@ -791,44 +793,6 @@ static int vmci_transport_recv_stream_cb(void *data, struct vmci_datagram *dg)
return err;
}
-static void vmci_transport_peer_attach_cb(u32 sub_id,
- const struct vmci_event_data *e_data,
- void *client_data)
-{
- struct sock *sk = client_data;
- const struct vmci_event_payload_qp *e_payload;
- struct vsock_sock *vsk;
-
- e_payload = vmci_event_data_const_payload(e_data);
-
- vsk = vsock_sk(sk);
-
- /* We don't ask for delayed CBs when we subscribe to this event (we
- * pass 0 as flags to vmci_event_subscribe()). VMCI makes no
- * guarantees in that case about what context we might be running in,
- * so it could be BH or process, blockable or non-blockable. So we
- * need to account for all possible contexts here.
- */
- local_bh_disable();
- bh_lock_sock(sk);
-
- /* XXX This is lame, we should provide a way to lookup sockets by
- * qp_handle.
- */
- if (vmci_handle_is_equal(vmci_trans(vsk)->qp_handle,
- e_payload->handle)) {
- /* XXX This doesn't do anything, but in the future we may want
- * to set a flag here to verify the attach really did occur and
- * we weren't just sent a datagram claiming it was.
- */
- goto out;
- }
-
-out:
- bh_unlock_sock(sk);
- local_bh_enable();
-}
-
static void vmci_transport_handle_detach(struct sock *sk)
{
struct vsock_sock *vsk;
@@ -871,28 +835,38 @@ static void vmci_transport_peer_detach_cb(u32 sub_id,
const struct vmci_event_data *e_data,
void *client_data)
{
- struct sock *sk = client_data;
+ struct vmci_transport *trans = client_data;
const struct vmci_event_payload_qp *e_payload;
- struct vsock_sock *vsk;
e_payload = vmci_event_data_const_payload(e_data);
- vsk = vsock_sk(sk);
- if (vmci_handle_is_invalid(e_payload->handle))
- return;
-
- /* Same rules for locking as for peer_attach_cb(). */
- local_bh_disable();
- bh_lock_sock(sk);
/* XXX This is lame, we should provide a way to lookup sockets by
* qp_handle.
*/
- if (vmci_handle_is_equal(vmci_trans(vsk)->qp_handle,
- e_payload->handle))
- vmci_transport_handle_detach(sk);
+ if (vmci_handle_is_invalid(e_payload->handle) ||
+ vmci_handle_is_equal(trans->qp_handle, e_payload->handle))
+ return;
- bh_unlock_sock(sk);
- local_bh_enable();
+ /* We don't ask for delayed CBs when we subscribe to this event (we
+ * pass 0 as flags to vmci_event_subscribe()). VMCI makes no
+ * guarantees in that case about what context we might be running in,
+ * so it could be BH or process, blockable or non-blockable. So we
+ * need to account for all possible contexts here.
+ */
+ spin_lock_bh(&trans->lock);
+ if (!trans->sk)
+ goto out;
+
+ /* Apart from here, trans->lock is only grabbed as part of sk destruct,
+ * where trans->sk isn't locked.
+ */
+ bh_lock_sock(trans->sk);
+
+ vmci_transport_handle_detach(trans->sk);
+
+ bh_unlock_sock(trans->sk);
+ out:
+ spin_unlock_bh(&trans->lock);
}
static void vmci_transport_qp_resumed_cb(u32 sub_id,
@@ -1181,7 +1155,7 @@ vmci_transport_recv_connecting_server(struct sock *listener,
*/
err = vmci_event_subscribe(VMCI_EVENT_QP_PEER_DETACH,
vmci_transport_peer_detach_cb,
- pending, &detach_sub_id);
+ vmci_trans(vpending), &detach_sub_id);
if (err < VMCI_SUCCESS) {
vmci_transport_send_reset(pending, pkt);
err = vmci_transport_error_to_vsock_error(err);
@@ -1321,7 +1295,6 @@ vmci_transport_recv_connecting_client(struct sock *sk,
|| vmci_trans(vsk)->qpair
|| vmci_trans(vsk)->produce_size != 0
|| vmci_trans(vsk)->consume_size != 0
- || vmci_trans(vsk)->attach_sub_id != VMCI_INVALID_ID
|| vmci_trans(vsk)->detach_sub_id != VMCI_INVALID_ID) {
skerr = EPROTO;
err = -EINVAL;
@@ -1389,7 +1362,6 @@ static int vmci_transport_recv_connecting_client_negotiate(
struct vsock_sock *vsk;
struct vmci_handle handle;
struct vmci_qp *qpair;
- u32 attach_sub_id;
u32 detach_sub_id;
bool is_local;
u32 flags;
@@ -1399,7 +1371,6 @@ static int vmci_transport_recv_connecting_client_negotiate(
vsk = vsock_sk(sk);
handle = VMCI_INVALID_HANDLE;
- attach_sub_id = VMCI_INVALID_ID;
detach_sub_id = VMCI_INVALID_ID;
/* If we have gotten here then we should be past the point where old
@@ -1444,23 +1415,15 @@ static int vmci_transport_recv_connecting_client_negotiate(
goto destroy;
}
- /* Subscribe to attach and detach events first.
+ /* Subscribe to detach events first.
*
* XXX We attach once for each queue pair created for now so it is easy
* to find the socket (it's provided), but later we should only
* subscribe once and add a way to lookup sockets by queue pair handle.
*/
- err = vmci_event_subscribe(VMCI_EVENT_QP_PEER_ATTACH,
- vmci_transport_peer_attach_cb,
- sk, &attach_sub_id);
- if (err < VMCI_SUCCESS) {
- err = vmci_transport_error_to_vsock_error(err);
- goto destroy;
- }
-
err = vmci_event_subscribe(VMCI_EVENT_QP_PEER_DETACH,
vmci_transport_peer_detach_cb,
- sk, &detach_sub_id);
+ vmci_trans(vsk), &detach_sub_id);
if (err < VMCI_SUCCESS) {
err = vmci_transport_error_to_vsock_error(err);
goto destroy;
@@ -1496,7 +1459,6 @@ static int vmci_transport_recv_connecting_client_negotiate(
vmci_trans(vsk)->produce_size = vmci_trans(vsk)->consume_size =
pkt->u.size;
- vmci_trans(vsk)->attach_sub_id = attach_sub_id;
vmci_trans(vsk)->detach_sub_id = detach_sub_id;
vmci_trans(vsk)->notify_ops->process_negotiate(sk);
@@ -1504,9 +1466,6 @@ static int vmci_transport_recv_connecting_client_negotiate(
return 0;
destroy:
- if (attach_sub_id != VMCI_INVALID_ID)
- vmci_event_unsubscribe(attach_sub_id);
-
if (detach_sub_id != VMCI_INVALID_ID)
vmci_event_unsubscribe(detach_sub_id);
@@ -1607,9 +1566,11 @@ static int vmci_transport_socket_init(struct vsock_sock *vsk,
vmci_trans(vsk)->qp_handle = VMCI_INVALID_HANDLE;
vmci_trans(vsk)->qpair = NULL;
vmci_trans(vsk)->produce_size = vmci_trans(vsk)->consume_size = 0;
- vmci_trans(vsk)->attach_sub_id = vmci_trans(vsk)->detach_sub_id =
- VMCI_INVALID_ID;
+ vmci_trans(vsk)->detach_sub_id = VMCI_INVALID_ID;
vmci_trans(vsk)->notify_ops = NULL;
+ INIT_LIST_HEAD(&vmci_trans(vsk)->elem);
+ vmci_trans(vsk)->sk = &vsk->sk;
+ vmci_trans(vsk)->lock = __SPIN_LOCK_UNLOCKED(vmci_trans(vsk)->lock);
if (psk) {
vmci_trans(vsk)->queue_pair_size =
vmci_trans(psk)->queue_pair_size;
@@ -1629,29 +1590,57 @@ static int vmci_transport_socket_init(struct vsock_sock *vsk,
return 0;
}
-static void vmci_transport_destruct(struct vsock_sock *vsk)
+static void vmci_transport_free_resources(struct list_head *transport_list)
{
- if (vmci_trans(vsk)->attach_sub_id != VMCI_INVALID_ID) {
- vmci_event_unsubscribe(vmci_trans(vsk)->attach_sub_id);
- vmci_trans(vsk)->attach_sub_id = VMCI_INVALID_ID;
- }
+ while (!list_empty(transport_list)) {
+ struct vmci_transport *transport =
+ list_first_entry(transport_list, struct vmci_transport,
+ elem);
+ list_del(&transport->elem);
- if (vmci_trans(vsk)->detach_sub_id != VMCI_INVALID_ID) {
- vmci_event_unsubscribe(vmci_trans(vsk)->detach_sub_id);
- vmci_trans(vsk)->detach_sub_id = VMCI_INVALID_ID;
- }
+ if (transport->detach_sub_id != VMCI_INVALID_ID) {
+ vmci_event_unsubscribe(transport->detach_sub_id);
+ transport->detach_sub_id = VMCI_INVALID_ID;
+ }
- if (!vmci_handle_is_invalid(vmci_trans(vsk)->qp_handle)) {
- vmci_qpair_detach(&vmci_trans(vsk)->qpair);
- vmci_trans(vsk)->qp_handle = VMCI_INVALID_HANDLE;
- vmci_trans(vsk)->produce_size = 0;
- vmci_trans(vsk)->consume_size = 0;
+ if (!vmci_handle_is_invalid(transport->qp_handle)) {
+ vmci_qpair_detach(&transport->qpair);
+ transport->qp_handle = VMCI_INVALID_HANDLE;
+ transport->produce_size = 0;
+ transport->consume_size = 0;
+ }
+
+ kfree(transport);
}
+}
+
+static void vmci_transport_cleanup(struct work_struct *work)
+{
+ LIST_HEAD(pending);
+
+ spin_lock_bh(&vmci_transport_cleanup_lock);
+ list_replace_init(&vmci_transport_cleanup_list, &pending);
+ spin_unlock_bh(&vmci_transport_cleanup_lock);
+ vmci_transport_free_resources(&pending);
+}
+
+static void vmci_transport_destruct(struct vsock_sock *vsk)
+{
+ /* Ensure that the detach callback doesn't use the sk/vsk
+ * we are about to destruct.
+ */
+ spin_lock_bh(&vmci_trans(vsk)->lock);
+ vmci_trans(vsk)->sk = NULL;
+ spin_unlock_bh(&vmci_trans(vsk)->lock);
if (vmci_trans(vsk)->notify_ops)
vmci_trans(vsk)->notify_ops->socket_destruct(vsk);
- kfree(vsk->trans);
+ spin_lock_bh(&vmci_transport_cleanup_lock);
+ list_add(&vmci_trans(vsk)->elem, &vmci_transport_cleanup_list);
+ spin_unlock_bh(&vmci_transport_cleanup_lock);
+ schedule_work(&vmci_transport_cleanup_work);
+
vsk->trans = NULL;
}
@@ -2148,6 +2137,9 @@ module_init(vmci_transport_init);
static void __exit vmci_transport_exit(void)
{
+ cancel_work_sync(&vmci_transport_cleanup_work);
+ vmci_transport_free_resources(&vmci_transport_cleanup_list);
+
if (!vmci_handle_is_invalid(vmci_transport_stream_handle)) {
if (vmci_datagram_destroy_handle(
vmci_transport_stream_handle) != VMCI_SUCCESS)
@@ -2166,6 +2158,7 @@ module_exit(vmci_transport_exit);
MODULE_AUTHOR("VMware, Inc.");
MODULE_DESCRIPTION("VMCI transport for Virtual Sockets");
+MODULE_VERSION("1.0.2.0-k");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("vmware_vsock");
MODULE_ALIAS_NETPROTO(PF_VSOCK);
diff --git a/net/vmw_vsock/vmci_transport.h b/net/vmw_vsock/vmci_transport.h
index ce6c9623d5f0..2ad46f39649f 100644
--- a/net/vmw_vsock/vmci_transport.h
+++ b/net/vmw_vsock/vmci_transport.h
@@ -119,10 +119,12 @@ struct vmci_transport {
u64 queue_pair_size;
u64 queue_pair_min_size;
u64 queue_pair_max_size;
- u32 attach_sub_id;
u32 detach_sub_id;
union vmci_transport_notify notify;
struct vmci_transport_notify_ops *notify_ops;
+ struct list_head elem;
+ struct sock *sk;
+ spinlock_t lock; /* protects sk. */
};
int vmci_transport_register(void);
--
2.14.1
^ permalink raw reply related
* HTB going crazy over ~5Gbit/s (4.12.9, but problem present in older kernels as well)
From: Denys Fedoryshchenko @ 2017-09-13 15:20 UTC (permalink / raw)
To: Linux Kernel Network Developers
Hi,
I noticed after increasing bandwidth over some amount HTB started to
throttle classes it should not throttle.
Also estimated rate in htb totally wrong, while byte counters is
correct.
Is there any overflow or something?
X520 card (but XL710 same)
br1 8000.90e2ba86c38c no eth3.1777
eth3.777
br2 8000.90e2ba86c38d no eth3.360
eth3.361
Inbound traffic is coming over one vlan, leaving another vlan.
Shaper is just bunch of classes and u32 filters, with few fw filters.
qdisc is pie
I put totally high values to not reach them, tried to change
quantum/burst/cburst but... stats below.
First, "root" class is 1:1 showing rate 18086Mbit, which is physically
impossible.
Class 1:111 showing 5355Mbit, while real traffic is ~1.5Gbit
shaper /etc # tc -s -d class show dev eth3.777 classid 1:111;sleep 5;tc
-s -d class show dev eth3.777 classid 1:111
class htb 1:111 parent 1:1 leaf 111: prio 0 quantum 50000 rate 10Gbit
ceil 100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu 0b
level 0
Sent 6487632263 bytes 5235525 pkt (dropped 0, overlimits 0 requeues 0)
rate 5529Mbit 557534pps backlog 0b 0p requeues 0
lended: 2423323 borrowed: 0 giants: 0
tokens: 124 ctokens: -1
class htb 1:111 parent 1:1 leaf 111: prio 0 quantum 50000 rate 10Gbit
ceil 100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu 0b
level 0
Sent 7438601731 bytes 6003811 pkt (dropped 0, overlimits 0 requeues 0)
rate 5631Mbit 568214pps backlog 36624b 8p requeues 0
lended: 2772486 borrowed: 0 giants: 0
tokens: 124 ctokens: -1
(7438601731-6487632263)/5*8 = 1.521.551.148
And most important some classes suffering, while they should not (not
reaching limits)
class htb 1:95 parent 1:1 leaf 95: prio 0 quantum 50000 rate 10Gbit ceil
100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu 0b
level 0
Sent 13556762059 bytes 17474559 pkt (dropped 16017, overlimits 0
requeues 0)
rate 2524Mbit 414197pps backlog 31969245b 34513p requeues 0
lended: 13995723 borrowed: 0 giants: 0
tokens: 111 ctokens: -2
Full classes stats:
class htb 1:100 parent 1:1 leaf 100: prio 0 quantum 50000 rate 10Gbit
ceil 100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu 0b
level 0
Sent 116 bytes 2 pkt (dropped 0, overlimits 0 requeues 0)
rate 8bit 0pps backlog 0b 0p requeues 0
lended: 2 borrowed: 0 giants: 0
tokens: 124 ctokens: -1
class htb 1:120 parent 1:1 leaf 120: prio 0 quantum 50000 rate 10Gbit
ceil 100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu 0b
level 0
Sent 531230043 bytes 782130 pkt (dropped 0, overlimits 0 requeues 0)
rate 132274Kbit 25240pps backlog 0b 0p requeues 0
lended: 540693 borrowed: 0 giants: 0
tokens: 109 ctokens: -2
class htb 1:50 parent 1:1 leaf 50: prio 0 quantum 50000 rate 10Gbit ceil
100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu 0b
level 0
Sent 773472109 bytes 587335 pkt (dropped 0, overlimits 0 requeues 0)
rate 215929Kbit 20503pps backlog 0b 0p requeues 0
lended: 216614 borrowed: 0 giants: 0
tokens: 91 ctokens: -4
class htb 1:70 parent 1:1 leaf 70: prio 0 quantum 50000 rate 10Gbit ceil
100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu 0b
level 0
Sent 1574768 bytes 6194 pkt (dropped 0, overlimits 0 requeues 0)
rate 406272bit 214pps backlog 0b 0p requeues 0
lended: 5758 borrowed: 0 giants: 0
tokens: 101 ctokens: -3
class htb 1:90 parent 1:1 leaf 90: prio 0 quantum 50000 rate 1Kbit ceil
100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu 0b
level 0
Sent 3206 bytes 53 pkt (dropped 0, overlimits 0 requeues 0)
rate 848bit 1pps backlog 0b 0p requeues 0
lended: 53 borrowed: 0 giants: 0
class htb 1:110 parent 1:1 leaf 110: prio 0 quantum 50000 rate 10Gbit
ceil 100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu 0b
level 0
Sent 17205952113 bytes 12926008 pkt (dropped 239, overlimits 0 requeues
0)
rate 4433Mbit 416825pps backlog 5847785b 2394p requeues 0
lended: 7021696 borrowed: 0 giants: 0
tokens: 91 ctokens: -4
class htb 1:45 root leaf 45: prio 0 quantum 50000 rate 80Mbit ceil
80Mbit linklayer ethernet burst 10000b/1 mpu 0b cburst 10000b/1 mpu 0b
level 0
Sent 2586 bytes 45 pkt (dropped 0, overlimits 0 requeues 0)
rate 456bit 1pps backlog 0b 0p requeues 0
lended: 45 borrowed: 0 giants: 0
tokens: 15540 ctokens: 15540
class htb 1:1 root rate 100Gbit ceil 100Gbit linklayer ethernet burst
0b/1 mpu 0b cburst 0b/1 mpu 0b level 7
Sent 72277215121 bytes 72693012 pkt (dropped 0, overlimits 0 requeues
0)
rate 18086Mbit 2304729pps backlog 0b 0p requeues 0
lended: 0 borrowed: 0 giants: 0
tokens: -4 ctokens: -4
class htb 1:111 parent 1:1 leaf 111: prio 0 quantum 50000 rate 10Gbit
ceil 100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu 0b
level 0
Sent 21977384237 bytes 17697345 pkt (dropped 391, overlimits 0 requeues
0)
rate 5355Mbit 543216pps backlog 41746345b 14743p requeues 0
lended: 8837667 borrowed: 0 giants: 0
tokens: 124 ctokens: -1
class htb 1:200 parent 1:1 leaf 200: prio 0 quantum 50000 rate 10Gbit
ceil 100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu 0b
level 0
Sent 9209112058 bytes 10941655 pkt (dropped 5396413, overlimits 0
requeues 0)
rate 2142Mbit 326938pps backlog 20798724b 25717p requeues 0
lended: 9926866 borrowed: 0 giants: 0
tokens: 108 ctokens: -2
class htb 1:20 parent 1:1 leaf 20: prio 0 quantum 50000 rate 10Gbit ceil
100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu 0b
level 0
Sent 1504918577 bytes 1170037 pkt (dropped 0, overlimits 0 requeues 0)
rate 413892Kbit 40322pps backlog 0b 0p requeues 0
lended: 497069 borrowed: 0 giants: 0
tokens: 92 ctokens: -4
class htb 1:40 parent 1:1 leaf 40: prio 0 quantum 50000 rate 1Gbit ceil
1Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 10000b/1 mpu 0b
level 0
Sent 8638241052 bytes 9526035 pkt (dropped 0, overlimits 0 requeues 0)
rate 2442Mbit 333804pps backlog 0b 0p requeues 0
lended: 6947694 borrowed: 0 giants: 0
tokens: 1064 ctokens: 1064
class htb 1:60 parent 1:1 leaf 60: prio 0 quantum 50000 rate 10Gbit ceil
100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu 0b
level 0
Sent 3124889750 bytes 6972789 pkt (dropped 5833, overlimits 0 requeues
0)
rate 824981Kbit 233296pps backlog 616b 3p requeues 0
lended: 6701559 borrowed: 0 giants: 0
tokens: 122 ctokens: -1
class htb 1:25 parent 1:1 leaf 25: prio 0 quantum 50000 rate 10Gbit ceil
100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu 0b
level 0
Sent 3275 bytes 57 pkt (dropped 0, overlimits 0 requeues 0)
rate 504bit 1pps backlog 0b 0p requeues 0
lended: 57 borrowed: 0 giants: 0
tokens: 123 ctokens: -1
class htb 1:80 parent 1:1 leaf 80: prio 0 quantum 50000 rate 10Gbit ceil
100Gbit linklayer ethernet burst 10000b/1 mpu 0b cburst 0b/1 mpu 0b
level 0
Sent 2598 bytes 45 pkt (dropped 0, overlimits 0 requeues 0)
rate 672bit 1pps backlog 0b 0p requeues 0
lended: 45 borrowed: 0 giants: 0
tokens: 124 ctokens: -1
tc -s -d qdisc show dev eth3.777
qdisc htb 1: root refcnt 2 r2q 10 default 200 direct_packets_stat 6858
ver 3.17 direct_qlen 1000
Sent 185271955178 bytes 186767377 pkt (dropped 14248387, overlimits 0
requeues 0)
backlog 62369772b 68728p requeues 0
qdisc pie 120: parent 1:120 limit 40000p target 200.0ms tupdate 30.0ms
alpha 2 beta 20
Sent 1532094051 bytes 2108158 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
prob 0.000000 delay 0us avg_dq_rate 0
pkts_in 1424069 overlimit 0 dropped 0 maxq 96 ecn_mark 0
qdisc pie 95: parent 1:95 limit 40000p target 250.0ms tupdate 30.0ms
alpha 2 beta 20
Sent 24359099839 bytes 31531160 pkt (dropped 36527, overlimits 0
requeues 0)
backlog 27116831b 28680p requeues 0
prob 0.000000 delay 82019us avg_dq_rate 96252441
pkts_in 25249681 overlimit 2107 dropped 36527 maxq 39999 ecn_mark 0
qdisc pie 80: parent 1:80 limit 40000p target 250.0ms tupdate 30.0ms
alpha 2 beta 20
Sent 19695 bytes 317 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
prob 0.000000 delay 0us avg_dq_rate 0
pkts_in 317 overlimit 0 dropped 0 maxq 1 ecn_mark 0
qdisc pie 111: parent 1:111 limit 40000p target 200.0ms tupdate 300.0ms
alpha 2 beta 20
Sent 57513872600 bytes 46387754 pkt (dropped 0, overlimits 0 requeues
0)
backlog 126218b 49p requeues 0
prob 0.000000 delay 227us avg_dq_rate 184143066
qdisc pie 100: parent 1:100 limit 40000p target 200.0ms tupdate 30.0ms
alpha 2 beta 20
Sent 494 bytes 9 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
prob 0.000000 delay 0us avg_dq_rate 0
pkts_in 9 overlimit 0 dropped 0 maxq 0 ecn_mark 0
qdisc pie 60: parent 1:60 limit 40000p target 250.0ms tupdate 30.0ms
alpha 2 beta 20
Sent 8749993535 bytes 18718111 pkt (dropped 0, overlimits 0 requeues 0)
backlog 7875b 14p requeues 0
prob 0.000000 delay 98us avg_dq_rate 0
pkts_in 17978754 overlimit 0 dropped 0 maxq 281 ecn_mark 0
qdisc pie 25: parent 1:25 limit 40000p target 250.0ms tupdate 30.0ms
alpha 2 beta 20
Sent 9412 bytes 135 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
prob 0.000000 delay 0us avg_dq_rate 0
pkts_in 135 overlimit 0 dropped 0 maxq 0 ecn_mark 0
qdisc pie 200: parent 1:200 limit 40000p target 50.0ms tupdate 30.0ms
alpha 2 beta 20
Sent 22224392951 bytes 26861660 pkt (dropped 14211817, overlimits 0
requeues 0)
backlog 35124441b 39999p requeues 0
prob 0.000071 delay 23747us avg_dq_rate 66040039
pkts_in 25266532 overlimit 14160730 dropped 14211817 maxq 39999 ecn_mark
0
qdisc pie 90: parent 1:90 limit 40000p target 250.0ms tupdate 30.0ms
alpha 2 beta 20
Sent 7396 bytes 134 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
prob 0.000000 delay 0us avg_dq_rate 0
pkts_in 134 overlimit 0 dropped 0 maxq 0 ecn_mark 0
qdisc pie 40: parent 1:40 limit 40000p target 200.0ms tupdate 30.0ms
alpha 2 beta 20
Sent 21316494470 bytes 23786396 pkt (dropped 0, overlimits 0 requeues
0)
backlog 0b 0p requeues 0
prob 0.000000 delay 0us avg_dq_rate 2085892079
pkts_in 17465291 overlimit 0 dropped 0 maxq 184 ecn_mark 0
qdisc pie 110: parent 1:110 limit 40000p target 200.0ms tupdate 300.0ms
alpha 2 beta 20
Sent 44081304635 bytes 33108042 pkt (dropped 0, overlimits 0 requeues
0)
backlog 0b 0p requeues 0
prob 0.000000 delay 47us avg_dq_rate 201721191
pkts_in 17602600 overlimit 0 dropped 0 maxq 157 ecn_mark 0
qdisc pie 70: parent 1:70 limit 40000p target 250.0ms tupdate 30.0ms
alpha 2 beta 20
Sent 4992265 bytes 16959 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
prob 0.000000 delay 0us avg_dq_rate 0
pkts_in 15448 overlimit 0 dropped 0 maxq 3 ecn_mark 0
qdisc pie 20: parent 1:20 limit 40000p target 250.0ms tupdate 30.0ms
alpha 2 beta 20
Sent 3475884019 bytes 2717342 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
prob 0.000000 delay 0us avg_dq_rate 0
pkts_in 1186311 overlimit 0 dropped 0 maxq 41 ecn_mark 0
qdisc pie 50: parent 1:50 limit 40000p target 250.0ms tupdate 30.0ms
alpha 2 beta 20 ecn
Sent 1994354891 bytes 1511636 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
prob 0.000000 delay 0us avg_dq_rate 0
pkts_in 561648 overlimit 0 dropped 0 maxq 27 ecn_mark 0
More info about setup:
shaper /etc # ethtool -k eth3
Features for eth3:
rx-checksumming: on
tx-checksumming: on
tx-checksum-ipv4: off [fixed]
tx-checksum-ip-generic: on
tx-checksum-ipv6: off [fixed]
tx-checksum-fcoe-crc: on [fixed]
tx-checksum-sctp: on
scatter-gather: on
tx-scatter-gather: on
tx-scatter-gather-fraglist: off [fixed]
tcp-segmentation-offload: off
tx-tcp-segmentation: off
tx-tcp-ecn-segmentation: off [fixed]
tx-tcp-mangleid-segmentation: off
tx-tcp6-segmentation: off
udp-fragmentation-offload: off [fixed]
generic-segmentation-offload: on
generic-receive-offload: on
large-receive-offload: off
rx-vlan-offload: on
tx-vlan-offload: on
ntuple-filters: off
receive-hashing: on
highdma: on [fixed]
rx-vlan-filter: on
vlan-challenged: off [fixed]
tx-lockless: off [fixed]
netns-local: off [fixed]
tx-gso-robust: off [fixed]
tx-fcoe-segmentation: on [fixed]
tx-gre-segmentation: on
tx-gre-csum-segmentation: on
tx-ipxip4-segmentation: on
tx-ipxip6-segmentation: on
tx-udp_tnl-segmentation: on
tx-udp_tnl-csum-segmentation: on
rx-all: off
tx-vlan-stag-hw-insert: off [fixed]
rx-vlan-stag-hw-parse: off [fixed]
rx-vlan-stag-filter: off [fixed]
l2-fwd-offload: off
hw-tc-offload: off
esp-hw-offload: off [fixed]
esp-tx-csum-hw-offload: off [fixed]
shaper /etc # ethtool -k eth3.777
Features for eth3.777:
rx-checksumming: off [fixed]
tx-checksumming: on
tx-checksum-ipv4: off [fixed]
tx-checksum-ip-generic: on
tx-checksum-ipv6: off [fixed]
tx-checksum-fcoe-crc: on
tx-checksum-sctp: on
scatter-gather: on
tx-scatter-gather: on
tx-scatter-gather-fraglist: off [requested on]
tcp-segmentation-offload: off
tx-tcp-segmentation: off
tx-tcp-ecn-segmentation: off
tx-tcp-mangleid-segmentation: off
tx-tcp6-segmentation: off
udp-fragmentation-offload: on
generic-segmentation-offload: on
generic-receive-offload: on
large-receive-offload: off [fixed]
rx-vlan-offload: off [fixed]
tx-vlan-offload: off [fixed]
ntuple-filters: off [fixed]
receive-hashing: off [fixed]
highdma: on
rx-vlan-filter: off [fixed]
vlan-challenged: off [fixed]
tx-lockless: on [fixed]
netns-local: off [fixed]
tx-gso-robust: off [fixed]
tx-fcoe-segmentation: on
tx-gre-segmentation: off [fixed]
tx-gre-csum-segmentation: off [fixed]
tx-ipxip4-segmentation: off [fixed]
tx-ipxip6-segmentation: off [fixed]
tx-udp_tnl-segmentation: off [fixed]
tx-udp_tnl-csum-segmentation: off [fixed]
tx-gso-partial: off [fixed]
tx-sctp-segmentation: on
tx-esp-segmentation: off [fixed]
fcoe-mtu: off [requested on]
tx-nocache-copy: off
loopback: off [fixed]
rx-fcs: off [fixed]
rx-all: off [fixed]
tx-vlan-stag-hw-insert: off [fixed]
rx-vlan-stag-hw-parse: off [fixed]
rx-vlan-stag-filter: off [fixed]
l2-fwd-offload: off [fixed]
hw-tc-offload: off [fixed]
esp-hw-offload: off [fixed]
esp-tx-csum-hw-offload: off [fixed]
shaper /etc # ethtool -i eth3
driver: ixgbe
version: 5.0.0-k
firmware-version: 0x2b2c0001
expansion-rom-version:
bus-info: 0000:06:00.1
supports-statistics: yes
supports-test: yes
supports-eeprom-access: yes
supports-register-dump: yes
supports-priv-flags: yes
mpstat -P ALL 10
Linux 4.12.9-build-0132 (shaper) 09/13/17 _x86_64_ (32 CPU)
18:15:55 CPU %usr %nice %sys %iowait %irq %soft %steal
%guest %idle
18:16:05 all 0.00 0.00 0.00 0.00 0.00 0.63 0.00
0.00 99.37
18:16:05 0 0.00 0.00 0.13 0.00 0.00 0.13 0.00
0.00 99.73
18:16:05 1 0.00 0.00 0.00 0.00 0.00 1.34 0.00
0.00 98.66
18:16:05 2 0.00 0.00 0.00 0.00 0.00 1.32 0.00
0.00 98.68
18:16:05 3 0.00 0.00 0.00 0.00 0.00 1.81 0.00
0.00 98.19
18:16:05 4 0.00 0.00 0.00 0.00 0.00 1.78 0.00
0.00 98.22
18:16:05 5 0.00 0.00 0.00 0.00 0.00 1.77 0.00
0.00 98.23
18:16:05 6 0.00 0.00 0.00 0.00 0.00 1.77 0.00
0.00 98.23
18:16:05 7 0.00 0.00 0.00 0.00 0.00 0.00 0.00
0.00 100.00
18:16:05 8 0.00 0.00 0.00 0.00 0.00 0.15 0.00
0.00 99.85
18:16:05 9 0.00 0.00 0.00 0.00 0.00 0.00 0.00
0.00 100.00
18:16:05 10 0.00 0.00 0.00 0.00 0.00 0.15 0.00
0.00 99.85
18:16:05 11 0.00 0.00 0.00 0.00 0.00 0.00 0.00
0.00 100.00
18:16:05 12 0.00 0.00 0.00 0.00 0.00 0.48 0.00
0.00 99.52
18:16:05 13 0.00 0.00 0.00 0.00 0.00 0.59 0.00
0.00 99.41
18:16:05 14 0.00 0.00 0.00 0.00 0.00 1.30 0.00
0.00 98.70
18:16:05 15 0.00 0.00 0.00 0.00 0.00 0.00 0.00
0.00 100.00
18:16:05 16 0.00 0.00 0.00 0.00 0.00 0.12 0.00
0.00 99.88
18:16:05 17 0.00 0.00 0.00 0.00 0.00 0.82 0.00
0.00 99.18
18:16:05 18 0.00 0.00 0.00 0.00 0.00 0.71 0.00
0.00 99.29
18:16:05 19 0.00 0.00 0.00 0.00 0.00 0.71 0.00
0.00 99.29
18:16:05 20 0.00 0.00 0.00 0.00 0.00 0.72 0.00
0.00 99.28
18:16:05 21 0.00 0.00 0.00 0.00 0.00 0.59 0.00
0.00 99.41
18:16:05 22 0.00 0.00 0.00 0.00 0.00 1.30 0.00
0.00 98.70
18:16:05 23 0.00 0.00 0.00 0.00 0.00 1.18 0.00
0.00 98.82
18:16:05 24 0.00 0.00 0.00 0.00 0.00 0.00 0.00
0.00 100.00
18:16:05 25 0.00 0.00 0.00 0.00 0.00 0.84 0.00
0.00 99.16
18:16:05 26 0.00 0.00 0.00 0.00 0.00 0.00 0.00
0.00 100.00
18:16:05 27 0.00 0.00 0.00 0.00 0.00 0.85 0.00
0.00 99.15
18:16:05 28 0.00 0.00 0.00 0.00 0.00 0.00 0.00
0.00 100.00
18:16:05 29 0.00 0.00 0.12 0.00 0.00 0.12 0.00
0.00 99.76
18:16:05 30 0.00 0.00 0.00 0.00 0.00 0.00 0.00
0.00 100.00
18:16:05 31 0.00 0.00 0.00 0.00 0.00 0.00 0.00
0.00 100.00
^ permalink raw reply
* [PATCH net] be2net: fix TSO6/GSO issue causing TX-stall on Lancer/BEx
From: Suresh Reddy @ 2017-09-13 15:12 UTC (permalink / raw)
To: netdev
In-Reply-To: <Suresh.Reddy@broadcom.com>
IPv6 TSO requests with extension hdrs are a problem to the
Lancer and BEx chips. Workaround is to disable TSO6 feature
for such packets.
Also in Lancer chips, MSS less than 256 was resulting in TX stall.
Fix this by disabling GSO when MSS less than 256.
Signed-off-by: Suresh Reddy <suresh.reddy@broadcom.com>
---
drivers/net/ethernet/emulex/benet/be.h | 8 ++++++++
drivers/net/ethernet/emulex/benet/be_main.c | 14 ++++++++++++++
2 files changed, 22 insertions(+)
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index 674cf9d..8984c49 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -930,6 +930,14 @@ static inline bool is_ipv4_pkt(struct sk_buff *skb)
return skb->protocol == htons(ETH_P_IP) && ip_hdr(skb)->version == 4;
}
+static inline bool is_ipv6_ext_hdr(struct sk_buff *skb)
+{
+ if (ip_hdr(skb)->version == 6)
+ return ipv6_ext_hdr(ipv6_hdr(skb)->nexthdr);
+ else
+ return false;
+}
+
#define be_error_recovering(adapter) \
(adapter->flags & BE_FLAGS_TRY_RECOVERY)
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 319eee3..0e3d9f39 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -5089,6 +5089,20 @@ static netdev_features_t be_features_check(struct sk_buff *skb,
struct be_adapter *adapter = netdev_priv(dev);
u8 l4_hdr = 0;
+ if (skb_is_gso(skb)) {
+ /* IPv6 TSO requests with extension hdrs are a problem
+ * to Lancer and BE3 HW. Disable TSO6 feature.
+ */
+ if (!skyhawk_chip(adapter) && is_ipv6_ext_hdr(skb))
+ features &= ~NETIF_F_TSO6;
+
+ /* Lancer cannot handle the packet with MSS less than 256.
+ * Disable the GSO support in such cases
+ */
+ if (lancer_chip(adapter) && skb_shinfo(skb)->gso_size < 256)
+ features &= ~NETIF_F_GSO_MASK;
+ }
+
/* The code below restricts offload features for some tunneled and
* Q-in-Q packets.
* Offload features for normal (non tunnel) packets are unchanged.
--
1.8.3.1
^ permalink raw reply related
* Re: scheduling while atomic from vmci_transport_recv_stream_cb in 3.16 kernels
From: Michal Hocko @ 2017-09-13 15:19 UTC (permalink / raw)
To: Jorgen S. Hansen
Cc: Aditya Sarwade, Thomas Hellstrom, LKML, netdev@vger.kernel.org,
Masik Petr, Ben Hutchings, Sasha Levin, Stable tree
In-Reply-To: <B8A42FAB-9E16-4943-98F3-86FC8F195069@vmware.com>
On Wed 13-09-17 15:07:26, Jorgen S. Hansen wrote:
>
> > On Sep 12, 2017, at 11:08 AM, Michal Hocko <mhocko@kernel.org> wrote:
> >
> > Hi,
> > we are seeing the following splat with Debian 3.16 stable kernel
> >
> > BUG: scheduling while atomic: MATLAB/26771/0x00000100
> > Modules linked in: veeamsnap(O) hmac cbc cts nfsv4 dns_resolver rpcsec_gss_krb5 nfsd auth_rpcgss oid_registry nfs_acl nfs lockd fscache sunrpc vmw_vso$
> > CPU: 0 PID: 26771 Comm: MATLAB Tainted: G O 3.16.0-4-amd64 #1 Debian 3.16.7-ckt20-1+deb8u3
> > Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 09/21/2015
> > ffff88315c1e4c20 ffffffff8150db3f ffff88193f803dc8 ffffffff8150acdf
> > ffffffff815103a2 0000000000012f00 ffff8819423dbfd8 0000000000012f00
> > ffff88315c1e4c20 ffff88193f803dc8 ffff88193f803d50 ffff88193f803dc0
> > Call Trace:
> > <IRQ> [<ffffffff8150db3f>] ? dump_stack+0x41/0x51
> > [<ffffffff8150acdf>] ? __schedule_bug+0x48/0x55
> > [<ffffffff815103a2>] ? __schedule+0x5d2/0x700
> > [<ffffffff8150f9b9>] ? schedule_timeout+0x229/0x2a0
> > [<ffffffff8109ba70>] ? select_task_rq_fair+0x390/0x700
> > [<ffffffff8109f780>] ? check_preempt_wakeup+0x120/0x1d0
> > [<ffffffff81510eb8>] ? wait_for_completion+0xa8/0x120
> > [<ffffffff81096de0>] ? wake_up_state+0x10/0x10
> > [<ffffffff810c3da0>] ? call_rcu_bh+0x20/0x20
> > [<ffffffff810c180b>] ? wait_rcu_gp+0x4b/0x60
> > [<ffffffff810c17b0>] ? ftrace_raw_output_rcu_utilization+0x40/0x40
> > [<ffffffffa02ca6f5>] ? vmci_event_unsubscribe+0x75/0xb0 [vmw_vmci]
> > [<ffffffffa031f5cd>] ? vmci_transport_destruct+0x1d/0xe0 [vmw_vsock_vmci_transport]
> > [<ffffffffa03167e3>] ? vsock_sk_destruct+0x13/0x60 [vsock]
> > [<ffffffff81409f7a>] ? __sk_free+0x1a/0x130
> > [<ffffffffa0320218>] ? vmci_transport_recv_stream_cb+0x1e8/0x2d0 [vmw_vsock_vmci_transport]
> > [<ffffffffa02c9cba>] ? vmci_datagram_invoke_guest_handler+0xaa/0xd0 [vmw_vmci]
> > [<ffffffffa02cab51>] ? vmci_dispatch_dgs+0xc1/0x200 [vmw_vmci]
> > [<ffffffff8106c294>] ? tasklet_action+0xf4/0x100
> > [<ffffffff8106c681>] ? __do_softirq+0xf1/0x290
> > [<ffffffff8106ca55>] ? irq_exit+0x95/0xa0
> > [<ffffffff81516b22>] ? do_IRQ+0x52/0xe0
> > [<ffffffff8151496d>] ? common_interrupt+0x6d/0x6d
> >
> > AFAICS this has been fixed by 4ef7ea9195ea ("VSOCK: sock_put wasn't safe
> > to call in interrupt context") but this patch hasn't been backported to
> > stable trees. It applies cleanly on top of 3.16 stable tree but I am not
> > familiar with the code to send the backport to the stable maintainer
> > directly.
> >
> > Could you double check that the patch below (just a blind cherry-pick)
> > is correct and it doesn't need additional patches on top?
>
> Hi,
>
> The patch below has been used to fix the above issue by other distros
> - among them Redhat for the 3.10 kernel, so it should work for 3.16 as
> well.
Thanks for the confirmation. I do not see 4ef7ea9195ea ("VSOCK: sock_put
wasn't safe to call in interrupt context") in 3.10 stable branch
though.
> In addition to the patch above, there are two other patches that
> need to be applied on top for the fix to be correct:
>
> 8566b86ab9f0f45bc6f7dd422b21de9d0cf5415a "VSOCK: Fix lockdep issue."
>
> and
>
> 8ab18d71de8b07d2c4d6f984b718418c09ea45c5 "VSOCK: Detach QP check should filter out non matching QPs."
Good to know. I will send all three patches cherry-picked on top of the
current 3.16 stable branch. Could you have a look please?
--
Michal Hocko
SUSE Labs
^ permalink raw reply
* Re: [PATCH 10/10] fs:btrfs: return -ENOMEM on allocation failure.
From: David Sterba @ 2017-09-13 15:13 UTC (permalink / raw)
To: Allen Pais
Cc: linux-kernel, nouveau, linux-crypto, dri-devel,
MPT-FusionLinux.pdl, linux-scsi, netdev, megaraidlinux.pdl,
target-devel, linux-fbdev, linux-btrfs
In-Reply-To: <1505287939-14106-10-git-send-email-allen.lkml@gmail.com>
On Wed, Sep 13, 2017 at 01:02:19PM +0530, Allen Pais wrote:
> Signed-off-by: Allen Pais <allen.lkml@gmail.com>
> ---
> fs/btrfs/check-integrity.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c
> index 7d5a9b5..efa4c23 100644
> --- a/fs/btrfs/check-integrity.c
> +++ b/fs/btrfs/check-integrity.c
> @@ -2913,7 +2913,7 @@ int btrfsic_mount(struct btrfs_fs_info *fs_info,
> state = kvzalloc(sizeof(*state), GFP_KERNEL);
> if (!state) {
> pr_info("btrfs check-integrity: allocation failed!\n");
> - return -1;
> + return -ENOMEM;
Makes sense, also please fix the -1 a few lines below that also result
from failed memory allocation, indirectly from btrfsic_dev_state_alloc().
> }
>
> if (!btrfsic_is_initialized) {
> --
> 2.7.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: scheduling while atomic from vmci_transport_recv_stream_cb in 3.16 kernels
From: Jorgen S. Hansen @ 2017-09-13 15:07 UTC (permalink / raw)
To: Michal Hocko
Cc: Aditya Sarwade, Thomas Hellstrom, LKML, netdev@vger.kernel.org,
Masik Petr, Ben Hutchings, Sasha Levin, Stable tree
In-Reply-To: <20170912090852.qshtrioffwexkslw@dhcp22.suse.cz>
> On Sep 12, 2017, at 11:08 AM, Michal Hocko <mhocko@kernel.org> wrote:
>
> Hi,
> we are seeing the following splat with Debian 3.16 stable kernel
>
> BUG: scheduling while atomic: MATLAB/26771/0x00000100
> Modules linked in: veeamsnap(O) hmac cbc cts nfsv4 dns_resolver rpcsec_gss_krb5 nfsd auth_rpcgss oid_registry nfs_acl nfs lockd fscache sunrpc vmw_vso$
> CPU: 0 PID: 26771 Comm: MATLAB Tainted: G O 3.16.0-4-amd64 #1 Debian 3.16.7-ckt20-1+deb8u3
> Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 09/21/2015
> ffff88315c1e4c20 ffffffff8150db3f ffff88193f803dc8 ffffffff8150acdf
> ffffffff815103a2 0000000000012f00 ffff8819423dbfd8 0000000000012f00
> ffff88315c1e4c20 ffff88193f803dc8 ffff88193f803d50 ffff88193f803dc0
> Call Trace:
> <IRQ> [<ffffffff8150db3f>] ? dump_stack+0x41/0x51
> [<ffffffff8150acdf>] ? __schedule_bug+0x48/0x55
> [<ffffffff815103a2>] ? __schedule+0x5d2/0x700
> [<ffffffff8150f9b9>] ? schedule_timeout+0x229/0x2a0
> [<ffffffff8109ba70>] ? select_task_rq_fair+0x390/0x700
> [<ffffffff8109f780>] ? check_preempt_wakeup+0x120/0x1d0
> [<ffffffff81510eb8>] ? wait_for_completion+0xa8/0x120
> [<ffffffff81096de0>] ? wake_up_state+0x10/0x10
> [<ffffffff810c3da0>] ? call_rcu_bh+0x20/0x20
> [<ffffffff810c180b>] ? wait_rcu_gp+0x4b/0x60
> [<ffffffff810c17b0>] ? ftrace_raw_output_rcu_utilization+0x40/0x40
> [<ffffffffa02ca6f5>] ? vmci_event_unsubscribe+0x75/0xb0 [vmw_vmci]
> [<ffffffffa031f5cd>] ? vmci_transport_destruct+0x1d/0xe0 [vmw_vsock_vmci_transport]
> [<ffffffffa03167e3>] ? vsock_sk_destruct+0x13/0x60 [vsock]
> [<ffffffff81409f7a>] ? __sk_free+0x1a/0x130
> [<ffffffffa0320218>] ? vmci_transport_recv_stream_cb+0x1e8/0x2d0 [vmw_vsock_vmci_transport]
> [<ffffffffa02c9cba>] ? vmci_datagram_invoke_guest_handler+0xaa/0xd0 [vmw_vmci]
> [<ffffffffa02cab51>] ? vmci_dispatch_dgs+0xc1/0x200 [vmw_vmci]
> [<ffffffff8106c294>] ? tasklet_action+0xf4/0x100
> [<ffffffff8106c681>] ? __do_softirq+0xf1/0x290
> [<ffffffff8106ca55>] ? irq_exit+0x95/0xa0
> [<ffffffff81516b22>] ? do_IRQ+0x52/0xe0
> [<ffffffff8151496d>] ? common_interrupt+0x6d/0x6d
>
> AFAICS this has been fixed by 4ef7ea9195ea ("VSOCK: sock_put wasn't safe
> to call in interrupt context") but this patch hasn't been backported to
> stable trees. It applies cleanly on top of 3.16 stable tree but I am not
> familiar with the code to send the backport to the stable maintainer
> directly.
>
> Could you double check that the patch below (just a blind cherry-pick)
> is correct and it doesn't need additional patches on top?
Hi,
The patch below has been used to fix the above issue by other distros - among them Redhat for the 3.10 kernel, so it should work for 3.16 as well. In addition to the patch above, there are two other patches that need to be applied on top for the fix to be correct:
8566b86ab9f0f45bc6f7dd422b21de9d0cf5415a "VSOCK: Fix lockdep issue."
and
8ab18d71de8b07d2c4d6f984b718418c09ea45c5 "VSOCK: Detach QP check should filter out non matching QPs."
Thanks,
Jorgen
>
> Ben could you take this to your stable 3.16 branch if the patch is correct?
>
> I am CCing Sasha for 4.1 stable tree as well. I haven't checked whether
> pre 3.16 kernels are affected as well.
> ---
> commit fac774c40b5c512113b6373cad498f35bee7a409
> Author: Jorgen Hansen <jhansen@vmware.com>
> Date: Wed Oct 21 04:53:56 2015 -0700
>
> VSOCK: sock_put wasn't safe to call in interrupt context
>
> commit 4ef7ea9195ea73262cd9730fb54e1eb726da157b upstream.
>
> In the vsock vmci_transport driver, sock_put wasn't safe to call
> in interrupt context, since that may call the vsock destructor
> which in turn calls several functions that should only be called
> from process context. This change defers the callling of these
> functions to a worker thread. All these functions were
> deallocation of resources related to the transport itself.
>
> Furthermore, an unused callback was removed to simplify the
> cleanup.
>
> Multiple customers have been hitting this issue when using
> VMware tools on vSphere 2015.
>
> Also added a version to the vmci transport module (starting from
> 1.0.2.0-k since up until now it appears that this module was
> sharing version with vsock that is currently at 1.0.1.0-k).
>
> Reviewed-by: Aditya Asarwade <asarwade@vmware.com>
> Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
> Signed-off-by: Jorgen Hansen <jhansen@vmware.com>
> Signed-off-by: David S. Miller <davem@davemloft.net>
>
> diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
> index 9bb63ffec4f2..aed136d27b01 100644
> --- a/net/vmw_vsock/vmci_transport.c
> +++ b/net/vmw_vsock/vmci_transport.c
> @@ -40,13 +40,11 @@
>
> static int vmci_transport_recv_dgram_cb(void *data, struct vmci_datagram *dg);
> static int vmci_transport_recv_stream_cb(void *data, struct vmci_datagram *dg);
> -static void vmci_transport_peer_attach_cb(u32 sub_id,
> - const struct vmci_event_data *ed,
> - void *client_data);
> static void vmci_transport_peer_detach_cb(u32 sub_id,
> const struct vmci_event_data *ed,
> void *client_data);
> static void vmci_transport_recv_pkt_work(struct work_struct *work);
> +static void vmci_transport_cleanup(struct work_struct *work);
> static int vmci_transport_recv_listen(struct sock *sk,
> struct vmci_transport_packet *pkt);
> static int vmci_transport_recv_connecting_server(
> @@ -75,6 +73,10 @@ struct vmci_transport_recv_pkt_info {
> struct vmci_transport_packet pkt;
> };
>
> +static LIST_HEAD(vmci_transport_cleanup_list);
> +static DEFINE_SPINLOCK(vmci_transport_cleanup_lock);
> +static DECLARE_WORK(vmci_transport_cleanup_work, vmci_transport_cleanup);
> +
> static struct vmci_handle vmci_transport_stream_handle = { VMCI_INVALID_ID,
> VMCI_INVALID_ID };
> static u32 vmci_transport_qp_resumed_sub_id = VMCI_INVALID_ID;
> @@ -791,44 +793,6 @@ static int vmci_transport_recv_stream_cb(void *data, struct vmci_datagram *dg)
> return err;
> }
>
> -static void vmci_transport_peer_attach_cb(u32 sub_id,
> - const struct vmci_event_data *e_data,
> - void *client_data)
> -{
> - struct sock *sk = client_data;
> - const struct vmci_event_payload_qp *e_payload;
> - struct vsock_sock *vsk;
> -
> - e_payload = vmci_event_data_const_payload(e_data);
> -
> - vsk = vsock_sk(sk);
> -
> - /* We don't ask for delayed CBs when we subscribe to this event (we
> - * pass 0 as flags to vmci_event_subscribe()). VMCI makes no
> - * guarantees in that case about what context we might be running in,
> - * so it could be BH or process, blockable or non-blockable. So we
> - * need to account for all possible contexts here.
> - */
> - local_bh_disable();
> - bh_lock_sock(sk);
> -
> - /* XXX This is lame, we should provide a way to lookup sockets by
> - * qp_handle.
> - */
> - if (vmci_handle_is_equal(vmci_trans(vsk)->qp_handle,
> - e_payload->handle)) {
> - /* XXX This doesn't do anything, but in the future we may want
> - * to set a flag here to verify the attach really did occur and
> - * we weren't just sent a datagram claiming it was.
> - */
> - goto out;
> - }
> -
> -out:
> - bh_unlock_sock(sk);
> - local_bh_enable();
> -}
> -
> static void vmci_transport_handle_detach(struct sock *sk)
> {
> struct vsock_sock *vsk;
> @@ -871,28 +835,38 @@ static void vmci_transport_peer_detach_cb(u32 sub_id,
> const struct vmci_event_data *e_data,
> void *client_data)
> {
> - struct sock *sk = client_data;
> + struct vmci_transport *trans = client_data;
> const struct vmci_event_payload_qp *e_payload;
> - struct vsock_sock *vsk;
>
> e_payload = vmci_event_data_const_payload(e_data);
> - vsk = vsock_sk(sk);
> - if (vmci_handle_is_invalid(e_payload->handle))
> - return;
> -
> - /* Same rules for locking as for peer_attach_cb(). */
> - local_bh_disable();
> - bh_lock_sock(sk);
>
> /* XXX This is lame, we should provide a way to lookup sockets by
> * qp_handle.
> */
> - if (vmci_handle_is_equal(vmci_trans(vsk)->qp_handle,
> - e_payload->handle))
> - vmci_transport_handle_detach(sk);
> + if (vmci_handle_is_invalid(e_payload->handle) ||
> + vmci_handle_is_equal(trans->qp_handle, e_payload->handle))
> + return;
>
> - bh_unlock_sock(sk);
> - local_bh_enable();
> + /* We don't ask for delayed CBs when we subscribe to this event (we
> + * pass 0 as flags to vmci_event_subscribe()). VMCI makes no
> + * guarantees in that case about what context we might be running in,
> + * so it could be BH or process, blockable or non-blockable. So we
> + * need to account for all possible contexts here.
> + */
> + spin_lock_bh(&trans->lock);
> + if (!trans->sk)
> + goto out;
> +
> + /* Apart from here, trans->lock is only grabbed as part of sk destruct,
> + * where trans->sk isn't locked.
> + */
> + bh_lock_sock(trans->sk);
> +
> + vmci_transport_handle_detach(trans->sk);
> +
> + bh_unlock_sock(trans->sk);
> + out:
> + spin_unlock_bh(&trans->lock);
> }
>
> static void vmci_transport_qp_resumed_cb(u32 sub_id,
> @@ -1181,7 +1155,7 @@ vmci_transport_recv_connecting_server(struct sock *listener,
> */
> err = vmci_event_subscribe(VMCI_EVENT_QP_PEER_DETACH,
> vmci_transport_peer_detach_cb,
> - pending, &detach_sub_id);
> + vmci_trans(vpending), &detach_sub_id);
> if (err < VMCI_SUCCESS) {
> vmci_transport_send_reset(pending, pkt);
> err = vmci_transport_error_to_vsock_error(err);
> @@ -1321,7 +1295,6 @@ vmci_transport_recv_connecting_client(struct sock *sk,
> || vmci_trans(vsk)->qpair
> || vmci_trans(vsk)->produce_size != 0
> || vmci_trans(vsk)->consume_size != 0
> - || vmci_trans(vsk)->attach_sub_id != VMCI_INVALID_ID
> || vmci_trans(vsk)->detach_sub_id != VMCI_INVALID_ID) {
> skerr = EPROTO;
> err = -EINVAL;
> @@ -1389,7 +1362,6 @@ static int vmci_transport_recv_connecting_client_negotiate(
> struct vsock_sock *vsk;
> struct vmci_handle handle;
> struct vmci_qp *qpair;
> - u32 attach_sub_id;
> u32 detach_sub_id;
> bool is_local;
> u32 flags;
> @@ -1399,7 +1371,6 @@ static int vmci_transport_recv_connecting_client_negotiate(
>
> vsk = vsock_sk(sk);
> handle = VMCI_INVALID_HANDLE;
> - attach_sub_id = VMCI_INVALID_ID;
> detach_sub_id = VMCI_INVALID_ID;
>
> /* If we have gotten here then we should be past the point where old
> @@ -1444,23 +1415,15 @@ static int vmci_transport_recv_connecting_client_negotiate(
> goto destroy;
> }
>
> - /* Subscribe to attach and detach events first.
> + /* Subscribe to detach events first.
> *
> * XXX We attach once for each queue pair created for now so it is easy
> * to find the socket (it's provided), but later we should only
> * subscribe once and add a way to lookup sockets by queue pair handle.
> */
> - err = vmci_event_subscribe(VMCI_EVENT_QP_PEER_ATTACH,
> - vmci_transport_peer_attach_cb,
> - sk, &attach_sub_id);
> - if (err < VMCI_SUCCESS) {
> - err = vmci_transport_error_to_vsock_error(err);
> - goto destroy;
> - }
> -
> err = vmci_event_subscribe(VMCI_EVENT_QP_PEER_DETACH,
> vmci_transport_peer_detach_cb,
> - sk, &detach_sub_id);
> + vmci_trans(vsk), &detach_sub_id);
> if (err < VMCI_SUCCESS) {
> err = vmci_transport_error_to_vsock_error(err);
> goto destroy;
> @@ -1496,7 +1459,6 @@ static int vmci_transport_recv_connecting_client_negotiate(
> vmci_trans(vsk)->produce_size = vmci_trans(vsk)->consume_size =
> pkt->u.size;
>
> - vmci_trans(vsk)->attach_sub_id = attach_sub_id;
> vmci_trans(vsk)->detach_sub_id = detach_sub_id;
>
> vmci_trans(vsk)->notify_ops->process_negotiate(sk);
> @@ -1504,9 +1466,6 @@ static int vmci_transport_recv_connecting_client_negotiate(
> return 0;
>
> destroy:
> - if (attach_sub_id != VMCI_INVALID_ID)
> - vmci_event_unsubscribe(attach_sub_id);
> -
> if (detach_sub_id != VMCI_INVALID_ID)
> vmci_event_unsubscribe(detach_sub_id);
>
> @@ -1607,9 +1566,11 @@ static int vmci_transport_socket_init(struct vsock_sock *vsk,
> vmci_trans(vsk)->qp_handle = VMCI_INVALID_HANDLE;
> vmci_trans(vsk)->qpair = NULL;
> vmci_trans(vsk)->produce_size = vmci_trans(vsk)->consume_size = 0;
> - vmci_trans(vsk)->attach_sub_id = vmci_trans(vsk)->detach_sub_id =
> - VMCI_INVALID_ID;
> + vmci_trans(vsk)->detach_sub_id = VMCI_INVALID_ID;
> vmci_trans(vsk)->notify_ops = NULL;
> + INIT_LIST_HEAD(&vmci_trans(vsk)->elem);
> + vmci_trans(vsk)->sk = &vsk->sk;
> + vmci_trans(vsk)->lock = __SPIN_LOCK_UNLOCKED(vmci_trans(vsk)->lock);
> if (psk) {
> vmci_trans(vsk)->queue_pair_size =
> vmci_trans(psk)->queue_pair_size;
> @@ -1629,29 +1590,57 @@ static int vmci_transport_socket_init(struct vsock_sock *vsk,
> return 0;
> }
>
> -static void vmci_transport_destruct(struct vsock_sock *vsk)
> +static void vmci_transport_free_resources(struct list_head *transport_list)
> {
> - if (vmci_trans(vsk)->attach_sub_id != VMCI_INVALID_ID) {
> - vmci_event_unsubscribe(vmci_trans(vsk)->attach_sub_id);
> - vmci_trans(vsk)->attach_sub_id = VMCI_INVALID_ID;
> - }
> + while (!list_empty(transport_list)) {
> + struct vmci_transport *transport =
> + list_first_entry(transport_list, struct vmci_transport,
> + elem);
> + list_del(&transport->elem);
>
> - if (vmci_trans(vsk)->detach_sub_id != VMCI_INVALID_ID) {
> - vmci_event_unsubscribe(vmci_trans(vsk)->detach_sub_id);
> - vmci_trans(vsk)->detach_sub_id = VMCI_INVALID_ID;
> - }
> + if (transport->detach_sub_id != VMCI_INVALID_ID) {
> + vmci_event_unsubscribe(transport->detach_sub_id);
> + transport->detach_sub_id = VMCI_INVALID_ID;
> + }
>
> - if (!vmci_handle_is_invalid(vmci_trans(vsk)->qp_handle)) {
> - vmci_qpair_detach(&vmci_trans(vsk)->qpair);
> - vmci_trans(vsk)->qp_handle = VMCI_INVALID_HANDLE;
> - vmci_trans(vsk)->produce_size = 0;
> - vmci_trans(vsk)->consume_size = 0;
> + if (!vmci_handle_is_invalid(transport->qp_handle)) {
> + vmci_qpair_detach(&transport->qpair);
> + transport->qp_handle = VMCI_INVALID_HANDLE;
> + transport->produce_size = 0;
> + transport->consume_size = 0;
> + }
> +
> + kfree(transport);
> }
> +}
> +
> +static void vmci_transport_cleanup(struct work_struct *work)
> +{
> + LIST_HEAD(pending);
> +
> + spin_lock_bh(&vmci_transport_cleanup_lock);
> + list_replace_init(&vmci_transport_cleanup_list, &pending);
> + spin_unlock_bh(&vmci_transport_cleanup_lock);
> + vmci_transport_free_resources(&pending);
> +}
> +
> +static void vmci_transport_destruct(struct vsock_sock *vsk)
> +{
> + /* Ensure that the detach callback doesn't use the sk/vsk
> + * we are about to destruct.
> + */
> + spin_lock_bh(&vmci_trans(vsk)->lock);
> + vmci_trans(vsk)->sk = NULL;
> + spin_unlock_bh(&vmci_trans(vsk)->lock);
>
> if (vmci_trans(vsk)->notify_ops)
> vmci_trans(vsk)->notify_ops->socket_destruct(vsk);
>
> - kfree(vsk->trans);
> + spin_lock_bh(&vmci_transport_cleanup_lock);
> + list_add(&vmci_trans(vsk)->elem, &vmci_transport_cleanup_list);
> + spin_unlock_bh(&vmci_transport_cleanup_lock);
> + schedule_work(&vmci_transport_cleanup_work);
> +
> vsk->trans = NULL;
> }
>
> @@ -2148,6 +2137,9 @@ module_init(vmci_transport_init);
>
> static void __exit vmci_transport_exit(void)
> {
> + cancel_work_sync(&vmci_transport_cleanup_work);
> + vmci_transport_free_resources(&vmci_transport_cleanup_list);
> +
> if (!vmci_handle_is_invalid(vmci_transport_stream_handle)) {
> if (vmci_datagram_destroy_handle(
> vmci_transport_stream_handle) != VMCI_SUCCESS)
> @@ -2166,6 +2158,7 @@ module_exit(vmci_transport_exit);
>
> MODULE_AUTHOR("VMware, Inc.");
> MODULE_DESCRIPTION("VMCI transport for Virtual Sockets");
> +MODULE_VERSION("1.0.2.0-k");
> MODULE_LICENSE("GPL v2");
> MODULE_ALIAS("vmware_vsock");
> MODULE_ALIAS_NETPROTO(PF_VSOCK);
> diff --git a/net/vmw_vsock/vmci_transport.h b/net/vmw_vsock/vmci_transport.h
> index ce6c9623d5f0..2ad46f39649f 100644
> --- a/net/vmw_vsock/vmci_transport.h
> +++ b/net/vmw_vsock/vmci_transport.h
> @@ -119,10 +119,12 @@ struct vmci_transport {
> u64 queue_pair_size;
> u64 queue_pair_min_size;
> u64 queue_pair_max_size;
> - u32 attach_sub_id;
> u32 detach_sub_id;
> union vmci_transport_notify notify;
> struct vmci_transport_notify_ops *notify_ops;
> + struct list_head elem;
> + struct sock *sk;
> + spinlock_t lock; /* protects sk. */
> };
>
> int vmci_transport_register(void);
> --
> Michal Hocko
> SUSE Labs
^ permalink raw reply
* Re: netfilter: xt_bpf: ABI issue in xt_bpf_info_v1?
From: Willem de Bruijn @ 2017-09-13 15:05 UTC (permalink / raw)
To: Jan Engelhardt
Cc: Shmulik Ladkani, netfilter-devel, Pablo Neira Ayuso,
Network Development, Willem de Bruijn, Rafael Buchbinder,
Shmulik Ladkani, eyal
In-Reply-To: <nycvar.YFH.7.76.1709131613520.8761@n3.vanv.qr>
On Wed, Sep 13, 2017 at 10:22 AM, Jan Engelhardt <jengelh@inai.de> wrote:
>
> On Wednesday 2017-09-13 15:24, Shmulik Ladkani wrote:
>>
>>One way to fix is to have iptables open the object (using the stored
>>xt_bpf_info_v1->path), gaining a new process local fd for the object,
>>just after getting the rules from IPT_SO_GET_ENTRIES.
>>However we didn't see any other extensions doing something like that in
>>iptables.
The binary should call bpf_obj_get on the filepath each time. These are
not regular files, but references to a pinned object in the bpf filesystem.
Blindly passing back the fd received from the kernel is clearly wrong. I'm
really surprised that I did not run into this problem when I wrote the
feature.
>>
>>Another way to solve is to fix the ABI (or have a v2 one), that does NOT
>>pass the fd from userspace, only the path of the pinned object.
>>Then, 'bpf_mt_check_v1' will open the file from the given path in order
>>to get the bpf_prog.
>
> But a path has a similar problem like a file descriptor - it is local to a
> certain mount namespace.
Because these are pinned objects in the bpf filesystem, and there is
only one of those, it may be possible to lookup the object in the kernel
without relying on a process-local view of mount points.
>
> To load "large" blobs into the kernel, a pointer to user memory is a possible
> option. The downside is that such extra data is not retrievable from the kernel
> via the iptables setsockopts anymore - one could work around it with procfs, or
> just let it be.
>
> https://sourceforge.net/p/xtables-addons/xtables-addons/ci/master/tree/extensions/xt_geoip.c
> line 64+.
^ permalink raw reply
* Re: [PATCH 01/10] arch:powerpc: return -ENOMEM on failed allocation
From: Joe Perches @ 2017-09-13 14:53 UTC (permalink / raw)
To: Allen Pais, linux-kernel
Cc: nouveau, linux-crypto, dri-devel, MPT-FusionLinux.pdl, linux-scsi,
netdev, megaraidlinux.pdl, target-devel, linux-fbdev, linux-btrfs
In-Reply-To: <1505287939-14106-1-git-send-email-allen.lkml@gmail.com>
On Wed, 2017-09-13 at 13:02 +0530, Allen Pais wrote:
> Signed-off-by: Allen Pais <allen.lkml@gmail.com>
I think the changelog for this series of conversions
should show that you've validated the change by
inspecting the return call chain at each modified line.
Also, it seems you've cc'd the same mailing lists for
all of the patches modified by this series.
It would be better to individually address each patch
in the series only cc'ing the appropriate maintainers
and mailing lists.
A cover letter would be good too.
> ---
> arch/powerpc/platforms/cell/spider-pci.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/platforms/cell/spider-pci.c b/arch/powerpc/platforms/cell/spider-pci.c
> index d1e61e2..82aa3f7 100644
> --- a/arch/powerpc/platforms/cell/spider-pci.c
> +++ b/arch/powerpc/platforms/cell/spider-pci.c
> @@ -106,7 +106,7 @@ static int __init spiderpci_pci_setup_chip(struct pci_controller *phb,
> dummy_page_va = kmalloc(PAGE_SIZE, GFP_KERNEL);
> if (!dummy_page_va) {
> pr_err("SPIDERPCI-IOWA:Alloc dummy_page_va failed.\n");
> - return -1;
> + return -ENOMEM;
> }
>
> dummy_page_da = dma_map_single(phb->parent, dummy_page_va,
> @@ -137,7 +137,7 @@ int __init spiderpci_iowa_init(struct iowa_bus *bus, void *data)
> if (!priv) {
> pr_err("SPIDERPCI-IOWA:"
> "Can't allocate struct spiderpci_iowa_private");
> - return -1;
> + return -ENOMEM;
> }
>
> if (of_address_to_resource(np, 0, &r)) {
^ permalink raw reply
* Re: [PATCH] dt-bindings: net: renesas-ravb: Add support for R8A77995 RAVB
From: Geert Uytterhoeven @ 2017-09-13 14:47 UTC (permalink / raw)
To: Yoshihiro Shimoda
Cc: David S. Miller, Rob Herring, Mark Rutland,
netdev@vger.kernel.org, Linux-Renesas, devicetree@vger.kernel.org
In-Reply-To: <1505305060-4192-1-git-send-email-yoshihiro.shimoda.uh@renesas.com>
On Wed, Sep 13, 2017 at 2:17 PM, Yoshihiro Shimoda
<yoshihiro.shimoda.uh@renesas.com> wrote:
> Add a new compatible string for the R8A77995 (R-Car D3) RAVB.
>
> Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Acked-by: Geert Uytterhoeven <geert+renesas@glider.be>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH] tcp: TCP_USER_TIMEOUT can not work in tcp_probe_timer()
From: Eric Dumazet @ 2017-09-13 14:40 UTC (permalink / raw)
To: liujian
Cc: davem, kuznet, yoshfuji, edumazet, ycheng, hkchu, netdev,
weiyongjun1, wangkefeng 00227729
In-Reply-To: <3c750ac3-8739-89ed-ce41-d4cde755171e@huawei.com>
On Wed, 2017-09-13 at 15:15 +0800, liujian wrote:
>
> 在 2017/9/13 14:56, liujian 写道:
> >
> >
> > 在 2017/9/12 23:38, Eric Dumazet 写道:
> >> On Tue, 2017-09-12 at 08:05 -0700, Eric Dumazet wrote:
> >>> On Tue, 2017-09-12 at 14:08 +0800, liujian wrote:
> >>>> Hi,
> >>>>
> >>>> In the scenario, tcp server side IP changed, and at that memont,
> >>>> userspace application still send data continuously;
> >>>> tcp_send_head(sk)'s timestamp always be refreshed.
> >>>>
> >>>> Here is the packetdrill script:
> >>>>
> >>>> 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
> >>>> +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
> >>>> +0 bind(3, ..., ...) = 0
> >>>> +0 listen(3, 1) = 0
> >>>>
> >>>> +0 < S 0:0(0) win 0 <mss 1460,sackOK,nop,nop,nop,wscale 7>
> >>>> +0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 7>
> >>>>
> >>>> +.1 < . 1:1(0) ack 1 win 65530
> >>>> +0 accept(3, ..., ...) = 4
> >>>>
> >>>> +0 setsockopt(4, SOL_TCP, TCP_USER_TIMEOUT, [3000], 4) = 0
> >>>> +0 write(4, ..., 24) = 24
> >>>> +0 > P. 1:25(24) ack 1 win 229
> >>>> +.1 < . 1:1(0) ack 25 win 65530
> >>>>
> >>>> //change the ipaddress
> >>>> +1 `ifconfig tun0 192.168.0.10/16`
> >>>>
> >>>> +1 write(4, ..., 24) = 24
> >>>> +1 write(4, ..., 24) = 24
> >>>> +1 write(4, ..., 24) = 24
> >>>> +1 write(4, ..., 24) = 24
> >>>> +3 write(4, ..., 24) = 24
> >>>> +3 write(4, ..., 24) = 24
> >>>> +3 write(4, ..., 24) = 24
> >>>> +3 write(4, ..., 24) = 24
> >>>> +3 write(4, ..., 24) = 24
> >>>> +3 write(4, ..., 24) = 24
> >>>> +3 write(4, ..., 24) = 24
> >>>> +3 write(4, ..., 24) = 24
> >>>> +3 write(4, ..., 24) = 24
> >>>> +3 write(4, ..., 24) = 24
> >>>> +3 write(4, ..., 24) = 24
> >>>> +3 write(4, ..., 24) = 24
> >>>> +3 write(4, ..., 24) = 24
> >>>> +3 write(4, ..., 24) = 24
> >>>> +3 write(4, ..., 24) = 24
> >>>> +3 write(4, ..., 24) = 24
> >>>> +3 write(4, ..., 24) = 24
> >>>> +3 write(4, ..., 24) = 24
> >>>> +3 write(4, ..., 24) = 24
> >>>> +3 write(4, ..., 24) = 24
> >>>> +3 write(4, ..., 24) = 24
> >>>> +3 write(4, ..., 24) = 24
> >>>>
> >>>> +0 `ifconfig tun0 192.168.0.1/16`
> >>>> +0 < . 1:1(0) ack 1 win 1000
> >>>> +0 write(4, ..., 24) = -1
> >>>>
> >>>>
> >>>
> >>> This has nothing to do with the code patch you have changed.
> >>>
> >>> How have you tested your patch exactly ?
> >>>
> > I tested the patch, it can work.
> >
> > [root@localhost ~]# time ./gtests/net/packetdrill/packetdrill test.pkt
> > test.pkt:24: runtime error in write call: Expected result 24 but got -1 with errno 110 (Connection timed out)
> >
> > real 0m5.356s
> > user 0m0.026s
> > sys 0m0.104s
> >
> > [root@localhost ~]# ss -toenmi src :8080
> > State Recv-Q Send-Q Local Address:Port Peer Address:Port
> > ESTAB 0 48 192.168.0.1:8080 192.0.2.1:39559 timer:(persist,186ms,2) ino:37178 sk:6 <->
> > skmem:(r0,rb369280,t0,tb87040,f1792,w2304,o0,bl0) sack cubic wscale:7,7 rto:301 backoff:2 rtt:100.253/37.643 mss:1460 cwnd:10 bytes_acked:24 segs_out:5 segs_in:3 send 1.2Mbps lastsnd:976 lastrcv:4082 lastack:3982 pacing_rate 2.3Mbps rcv_space:29200
> >
> >
> > if change the TCP_USER_TIMEOUT to 30s, test result as below:
> >
> > [root@localhost ~]# time ./gtests/net/packetdrill/packetdrill test.pkt
> > test.pkt:37: runtime error in write call: Expected result 24 but got -1 with errno 110 (Connection timed out)
> >
> > real 0m44.362s
> > user 0m0.018s
> > sys 0m0.110s
> >
> > ESTAB 0 360 192.168.0.1:8080 192.0.2.1:47577 timer:(persist,516ms,6) ino:18806 sk:5 <->
> > skmem:(r0,rb369280,t0,tb87040,f1792,w2304,o0,bl0) sack cubic wscale:7,7 rto:301 backoff:6 rtt:100.228/37.623 mss:10 bytes_acked:24 segs_out:22 segs_in:3 send 1.2Mbps lastsnd:2343 lastrcv:40450 lastack:40350 pacing_rate 2.3Mbps rcv_sp
> >
> >>
> >> lpaa23:~# ss -toenmi src :8080
> >> State Recv-Q Send-Q Local Address:Port Peer
> >> Address:Port
> >> ESTAB 0 144 192.168.134.161:8080
> >> 192.0.2.1:51165 timer:(persist,8.262ms,5) ino:1
> >> 82083 sk:3 <->
> >> skmem:(r0,rb359040,t0,tb46080,f1792,w2304,o0,bl0,d0) sack cubic
> >> wscale:7,8 rto:301 backoff:5 rtt:100.127/37.576
> >> mss:1460 rcvmss:536 advmss:1460 cwnd:10 bytes_acked:24 segs_out:12
> >> segs_in:3 data_segs_out:12 send 1.2Mbps lastsnd:1370 l
> >> astrcv:13348 lastack:13248 pacing_rate 2.3Mbps delivery_rate 116.7Kbps
> >> app_limited busy:11346ms rcv_space:29200 notsent:1
> >> 44 minrtt:100.043userspace application still send data continuously
> >>
> >> This is the typical RTO timer, not zero window probe.
> >>
> > with the script, it is not zero window; but the code enter tcp_probe_timer.
> > ->tcp_sendmsg
> > -->tcp_push
> > ---->__tcp_push_pending_frames
> > ------>tcp_write_xmit
> > -------->tcp_transmit_skb (at this function, tcp_send_head(sk)'s timestamp was be refreshed)
> > ---------->ip_queue_xmit (can not find route, return -EHOSTUNREACH)
> > -------->tcp_transmit_skb (send fail, do not advance send head)
> > ------->tcp_check_probe_timer (reset ICSK_TIME_PROBE0 timer)
> sorry, change to
> ->tcp_sendmsg
> -->tcp_push
> ---->__tcp_push_pending_frames
> ------>tcp_write_xmit
> -------->tcp_transmit_skb (at this function, tcp_send_head(sk)'s timestamp was be refreshed)
> ---------->ip_queue_xmit (can not find route, return -EHOSTUNREACH)
> ------>tcp_write_xmit (send fail, do not advance send head)
> ------>tcp_check_probe_timer (reset ICSK_TIME_PROBE0 timer)
OK but :
1) keepalive_time_elapsed() returns jiffies, and you compare it to a ms
value. It will break on kernels with HZ=100
2) keepalive_time_elapsed() is reset every time a packet is received.
With following packetdrill your patch (even if we fix 1)) breaks again
# ./packetdrill --local_ip 192.168.102.64 user_timeout.pkt
# cat user_timeout.pkt
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+0 bind(3, ..., ...) = 0
+0 listen(3, 1) = 0
+0 `ifconfig tun0 192.168.102.64/16; ip ro add 192.0.2.1 dev tun0`
+0 < S 0:0(0) win 0 <mss 1460,sackOK,nop,nop,nop,wscale 7>
+0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8>
+.1 < . 1:1(0) ack 1 win 65530
+0 accept(3, ..., ...) = 4
+0 setsockopt(4, SOL_TCP, TCP_USER_TIMEOUT, [3000], 4) = 0
+0 write(4, ..., 24) = 24
+0 > P. 1:25(24) ack 1 win 115
+.1 < . 1:1(0) ack 25 win 65530
//change the ipaddress
+1 `ifconfig tun0 192.168.0.10/16`
+1 write(4, ..., 24) = 24
+1 write(4, ..., 24) = 24
+1 write(4, ..., 24) = 24
+1 write(4, ..., 24) = 24
+0 `ifconfig tun0 192.168.102.64/16`
+0 < . 1:2(1) ack 25 win 65530
+0 `ifconfig tun0 192.168.0.10/16`
+3 write(4, ..., 24) = 24
+3 write(4, ..., 24) = 24
+3 write(4, ..., 24) = 24
+3 write(4, ..., 24) = 24
+3 write(4, ..., 24) = 24
+3 write(4, ..., 24) = 24
+3 write(4, ..., 24) = 24
+3 write(4, ..., 24) = 24
+3 write(4, ..., 24) = 24
+3 write(4, ..., 24) = 24
+3 write(4, ..., 24) = 24
+3 write(4, ..., 24) = 24
+3 write(4, ..., 24) = 24
+3 write(4, ..., 24) = 24
+3 write(4, ..., 24) = 24
+3 write(4, ..., 24) = 24
+3 write(4, ..., 24) = 24
+3 write(4, ..., 24) = 24
+3 write(4, ..., 24) = 24
+3 write(4, ..., 24) = 24
+3 write(4, ..., 24) = 24
+3 write(4, ..., 24) = 24
+0 `ifconfig tun0 192.168.0.1/16`
+0 < . 1:1(0) ack 1 win 1000
+0 write(4, ..., 24) = -1
I would instead try to keep a meaningful value in
tcp_send_head(sk)->skb_mstamp if the transmit failed.
Or more exactly change skb->skb_mstamp only on (successfully)
transmitted skb.
I will provide a patch ( fixing net/ipv4/tcp_output.c )
^ permalink raw reply
* Re: [PATCH net] sctp: potential read out of bounds in sctp_ulpevent_type_enabled()
From: Neil Horman @ 2017-09-13 14:28 UTC (permalink / raw)
To: Dan Carpenter
Cc: Vlad Yasevich, David S. Miller, linux-sctp, netdev,
kernel-janitors
In-Reply-To: <20170913092028.idzvduj7ran4li6b@mwanda>
On Wed, Sep 13, 2017 at 12:20:28PM +0300, Dan Carpenter wrote:
> This code causes a static checker warning because Smatch doesn't trust
> anything that comes from skb->data. I've reviewed this code and I do
> think skb->data can be controlled by the user here.
>
> The sctp_event_subscribe struct has 13 __u8 fields and we want to see
> if ours is non-zero. sn_type can be any value in the 0-USHRT_MAX range.
> We're subtracting SCTP_SN_TYPE_BASE which is 1 << 15 so we could read
> either before the start of the struct or after the end.
>
> This is a very old bug and it's surprising that it would go undetected
> for so long but my theory is that it just doesn't have a big impact so
> it would be hard to notice.
>
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
> ---
> I'm not terribly familiar with sctp and this is a static checker fix.
> Please review it carefully.
>
> diff --git a/include/net/sctp/ulpevent.h b/include/net/sctp/ulpevent.h
> index 1060494ac230..e6873176bea7 100644
> --- a/include/net/sctp/ulpevent.h
> +++ b/include/net/sctp/ulpevent.h
> @@ -154,7 +154,11 @@ static inline int sctp_ulpevent_type_enabled(__u16 sn_type,
> struct sctp_event_subscribe *mask)
> {
> char *amask = (char *) mask;
> - return amask[sn_type - SCTP_SN_TYPE_BASE];
> + int offset = sn_type - SCTP_SN_TYPE_BASE;
> +
> + if (offset >= sizeof(struct sctp_event_subscribe))
> + return 0;
> + return amask[offset];
> }
Acked-by: Neil Horman <nhorman@tuxdriver.com>
>
> /* Given an event subscription, is this event enabled? */
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sctp" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: netfilter: xt_bpf: ABI issue in xt_bpf_info_v1?
From: Jan Engelhardt @ 2017-09-13 14:22 UTC (permalink / raw)
To: Shmulik Ladkani
Cc: netfilter-devel, Pablo Neira Ayuso, netdev, Willem de Bruijn,
Rafael Buchbinder, shmulik.ladkani, eyal
In-Reply-To: <20170913162442.368691c9@pixies>
On Wednesday 2017-09-13 15:24, Shmulik Ladkani wrote:
>
>One way to fix is to have iptables open the object (using the stored
>xt_bpf_info_v1->path), gaining a new process local fd for the object,
>just after getting the rules from IPT_SO_GET_ENTRIES.
>However we didn't see any other extensions doing something like that in
>iptables.
>
>Another way to solve is to fix the ABI (or have a v2 one), that does NOT
>pass the fd from userspace, only the path of the pinned object.
>Then, 'bpf_mt_check_v1' will open the file from the given path in order
>to get the bpf_prog.
But a path has a similar problem like a file descriptor - it is local to a
certain mount namespace.
To load "large" blobs into the kernel, a pointer to user memory is a possible
option. The downside is that such extra data is not retrievable from the kernel
via the iptables setsockopts anymore - one could work around it with procfs, or
just let it be.
https://sourceforge.net/p/xtables-addons/xtables-addons/ci/master/tree/extensions/xt_geoip.c
line 64+.
^ permalink raw reply
* Re: [oss-drivers] Re: [PATCH/RFC net-next 2/2] net/sched: allow flower to match tunnel options
From: Simon Horman @ 2017-09-13 13:29 UTC (permalink / raw)
To: Or Gerlitz
Cc: Jiri Pirko, Jamal Hadi Salim, Cong Wang, Linux Netdev List,
oss-drivers
In-Reply-To: <CAJ3xEMj9HYj+2-ruxLk=PVt=Gxu3FwpyrJPRUgCqdsNamZ=Txw@mail.gmail.com>
On Wed, Sep 13, 2017 at 03:38:01PM +0300, Or Gerlitz wrote:
> On Wed, Sep 13, 2017 at 2:59 PM, Simon Horman
> <simon.horman@netronome.com> wrote:
> > On Wed, Sep 13, 2017 at 01:03:43PM +0300, Or Gerlitz wrote:
> >> On Wed, Sep 13, 2017 at 12:25 PM, Simon Horman
> >> <simon.horman@netronome.com> wrote:
> >> > On Tue, Sep 12, 2017 at 11:23:55PM +0300, Or Gerlitz wrote:
> >> >> On Tue, Sep 12, 2017 at 5:20 PM, Simon Horman
> >> >> <simon.horman@netronome.com> wrote:
> >> >> > Allow matching on options in tunnel headers.
> >> >> > This makes use of existing tunnel metadata support.
> >> >>
> >> >> Simon,
> >> >>
> >> >> This patch is about matching on tunnel options, right? but
> >> >>
> >> >> > Options are a bytestring of up to 256 bytes.
> >> >> > Tunnel implementations may support less or more options,
> >> >> > or no options at all.
> >> >> >
> >> >> > # ip link add name geneve0 type geneve dstport 0 external
> >> >> > # tc qdisc add dev eth0 ingress
> >> >> > # tc qdisc del dev eth0 ingress; tc qdisc add dev eth0 ingress
> >> >> > # tc filter add dev eth0 protocol ip parent ffff: \
> >> >> > flower indev eth0 \
> >> >> > ip_proto udp \
> >> >> > action tunnel_key \
> >> >> > set src_ip 10.0.99.192 \
> >> >> > dst_ip 10.0.99.193 \
> >> >> > dst_port 4789 \
> >> >> > id 11 \
> >> >> > opts 0102800100800022 \
> >> >> > action mirred egress redirect dev geneve0
> >> >>
> >> >> the example here is on how to use tunnel options in the tunnel set key actions..
> >> >>
> >> >> And the other way around in the other patch... the patch is about the
> >> >> tunnel key set action and the example shows how to match that in
> >> >> flower... I guess you want to swap the relevant of the change log.
> >> >
> >> > Yes, it seems so. Sorry about that.
> >>
> >> no worries, you can do the swap, but before that
> >>
> >> >> Anyway, is there any human readable/understandable representation of
> >> >> these options? e.g what does 0102800100800022 means for geneve?
> >>
> >> > Thanks, I had not thought of that. My feeling is that could
> >> > be added to the tc tool as follow-up work.
> >>
> >> could you spend few words on the nature of these options now when we review
> >> the kernel patches? I guess this is somehow related to protocols such
> >> as geneve and vxlan-gpe -- it would be good if you elaborate on that
> >> a bit, does
> >> the kernel does any usage with these options beyond matching on them or stiching
> >> them to packet headers?
> >
> > This feature is to be used in conjunction with tunnels in collect metadata
> > (external) mode. As I understand it there are three tunnel netdevs that use
> > options metadata in the kernel at this time.
> >
> > * Geneve
> >
> > In the case of Geneve options are TLVs[1]. My reading is that in collect
> > metadata mode the kernel does not appear to do anything other than pass
> > them around as a bytestring.
> >
> > [1] https://tools.ietf.org/html/draft-ietf-nvo3-geneve-05#section-3.5
> >
> > * VXLAN-GBP
> >
> > In the case of VXLAN-GBP on RX in collect metadata mode options are used
> > to carry information parsed in vxlan_parse_gbp_hdr() from the VXLAN Group
> > Based Policy Extension[2]. On RX the options data is used to create an
> > extension (header) by vxlan_build_gbp_hdr().
> >
> > [2] https://tools.ietf.org/html/draft-smith-vxlan-group-policy-03#section-2.1
> >
> > * ERSPAN (GRE)
> >
> > In the case of ERSPAN, which is a variant of GRE, on RX in collect
> > metadata mode options are used to carry the index parsed from the ERSPAN
> > Type II feature header[3] in erspan_rcv(). The converse is true on TX
> > and is handled by erspan_fb_xmit().
> >
> > [3] https://tools.ietf.org/html/draft-foschiano-erspan-03#section-4.2
> >
> > Users of options:
> >
> > * There are eBPF hooks to allow getting on and setting tunnel metadata:
> > bpf_skb_set_tunnel_opt, bpf_skb_get_tunnel_opt.
> >
> > * Open vSwitch is able to match and set Geneve and VXLAN-GBP options.
> >
> > Neither of the above appear to assume any structure for the data.
> >
> > I hope the above is the kind of information you are after.
>
> yeah, this helps, do we expect HW offloads to be able to work with
> these options? e.g place/match on packets
> or even do something beyond that?
Perhaps unsurprisingly given my posting I would like to offload
"place/match" of options. I do not currently have any plans beyond that
and my crystal ball broke some time ago.
^ permalink raw reply
* Re: [RFC PATCH v3 7/7] i40e: Enable cloud filters via tc-flower
From: Jiri Pirko @ 2017-09-13 13:26 UTC (permalink / raw)
To: Amritha Nambiar
Cc: intel-wired-lan, jeffrey.t.kirsher, alexander.h.duyck, netdev,
mlxsw
In-Reply-To: <150529679050.57063.3956015681929450874.stgit@anamdev.jf.intel.com>
Wed, Sep 13, 2017 at 11:59:50AM CEST, amritha.nambiar@intel.com wrote:
>This patch enables tc-flower based hardware offloads. tc flower
>filter provided by the kernel is configured as driver specific
>cloud filter. The patch implements functions and admin queue
>commands needed to support cloud filters in the driver and
>adds cloud filters to configure these tc-flower filters.
>
>The only action supported is to redirect packets to a traffic class
>on the same device.
So basically you are not doing redirect, you are just setting tclass for
matched packets, right? Why you use mirred for this? I think that
you might consider extending g_act for that:
# tc filter add dev eth0 protocol ip ingress \
prio 1 flower dst_mac 3c:fd:fe:a0:d6:70 skip_sw \
action tclass 0
>
># tc qdisc add dev eth0 ingress
># ethtool -K eth0 hw-tc-offload on
>
># tc filter add dev eth0 protocol ip parent ffff:\
> prio 1 flower dst_mac 3c:fd:fe:a0:d6:70 skip_sw\
> action mirred ingress redirect dev eth0 tclass 0
>
># tc filter add dev eth0 protocol ip parent ffff:\
> prio 2 flower dst_ip 192.168.3.5/32\
> ip_proto udp dst_port 25 skip_sw\
> action mirred ingress redirect dev eth0 tclass 1
>
># tc filter add dev eth0 protocol ipv6 parent ffff:\
> prio 3 flower dst_ip fe8::200:1\
> ip_proto udp dst_port 66 skip_sw\
> action mirred ingress redirect dev eth0 tclass 1
>
>Delete tc flower filter:
>Example:
>
># tc filter del dev eth0 parent ffff: prio 3 handle 0x1 flower
># tc filter del dev eth0 parent ffff:
>
>Flow Director Sideband is disabled while configuring cloud filters
>via tc-flower and until any cloud filter exists.
>
>Unsupported matches when cloud filters are added using enhanced
>big buffer cloud filter mode of underlying switch include:
>1. source port and source IP
>2. Combined MAC address and IP fields.
>3. Not specifying L4 port
>
>These filter matches can however be used to redirect traffic to
>the main VSI (tc 0) which does not require the enhanced big buffer
>cloud filter support.
>
>v3: Cleaned up some lengthy function names. Changed ipv6 address to
>__be32 array instead of u8 array. Used macro for IP version. Minor
>formatting changes.
>v2:
>1. Moved I40E_SWITCH_MODE_MASK definition to i40e_type.h
>2. Moved dev_info for add/deleting cloud filters in else condition
>3. Fixed some format specifier in dev_err logs
>4. Refactored i40e_get_capabilities to take an additional
> list_type parameter and use it to query device and function
> level capabilities.
>5. Fixed parsing tc redirect action to check for the is_tcf_mirred_tc()
> to verify if redirect to a traffic class is supported.
>6. Added comments for Geneve fix in cloud filter big buffer AQ
> function definitions.
>7. Cleaned up setup_tc interface to rebase and work with Jiri's
> updates, separate function to process tc cls flower offloads.
>8. Changes to make Flow Director Sideband and Cloud filters mutually
> exclusive.
>
>Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
>Signed-off-by: Kiran Patil <kiran.patil@intel.com>
>Signed-off-by: Anjali Singhai Jain <anjali.singhai@intel.com>
>Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
>---
> drivers/net/ethernet/intel/i40e/i40e.h | 49 +
> drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h | 3
> drivers/net/ethernet/intel/i40e/i40e_common.c | 189 ++++
> drivers/net/ethernet/intel/i40e/i40e_main.c | 971 +++++++++++++++++++-
> drivers/net/ethernet/intel/i40e/i40e_prototype.h | 16
> drivers/net/ethernet/intel/i40e/i40e_type.h | 1
> .../net/ethernet/intel/i40evf/i40e_adminq_cmd.h | 3
> 7 files changed, 1202 insertions(+), 30 deletions(-)
>
>diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h
>index 6018fb6..b110519 100644
>--- a/drivers/net/ethernet/intel/i40e/i40e.h
>+++ b/drivers/net/ethernet/intel/i40e/i40e.h
>@@ -55,6 +55,8 @@
> #include <linux/net_tstamp.h>
> #include <linux/ptp_clock_kernel.h>
> #include <net/pkt_cls.h>
>+#include <net/tc_act/tc_gact.h>
>+#include <net/tc_act/tc_mirred.h>
> #include "i40e_type.h"
> #include "i40e_prototype.h"
> #include "i40e_client.h"
>@@ -252,9 +254,52 @@ struct i40e_fdir_filter {
> u32 fd_id;
> };
>
>+#define IPV4_VERSION 4
>+#define IPV6_VERSION 6
>+
>+#define I40E_CLOUD_FIELD_OMAC 0x01
>+#define I40E_CLOUD_FIELD_IMAC 0x02
>+#define I40E_CLOUD_FIELD_IVLAN 0x04
>+#define I40E_CLOUD_FIELD_TEN_ID 0x08
>+#define I40E_CLOUD_FIELD_IIP 0x10
>+
>+#define I40E_CLOUD_FILTER_FLAGS_OMAC I40E_CLOUD_FIELD_OMAC
>+#define I40E_CLOUD_FILTER_FLAGS_IMAC I40E_CLOUD_FIELD_IMAC
>+#define I40E_CLOUD_FILTER_FLAGS_IMAC_IVLAN (I40E_CLOUD_FIELD_IMAC | \
>+ I40E_CLOUD_FIELD_IVLAN)
>+#define I40E_CLOUD_FILTER_FLAGS_IMAC_TEN_ID (I40E_CLOUD_FIELD_IMAC | \
>+ I40E_CLOUD_FIELD_TEN_ID)
>+#define I40E_CLOUD_FILTER_FLAGS_OMAC_TEN_ID_IMAC (I40E_CLOUD_FIELD_OMAC | \
>+ I40E_CLOUD_FIELD_IMAC | \
>+ I40E_CLOUD_FIELD_TEN_ID)
>+#define I40E_CLOUD_FILTER_FLAGS_IMAC_IVLAN_TEN_ID (I40E_CLOUD_FIELD_IMAC | \
>+ I40E_CLOUD_FIELD_IVLAN | \
>+ I40E_CLOUD_FIELD_TEN_ID)
>+#define I40E_CLOUD_FILTER_FLAGS_IIP I40E_CLOUD_FIELD_IIP
>+
> struct i40e_cloud_filter {
> struct hlist_node cloud_node;
> unsigned long cookie;
>+ /* cloud filter input set follows */
>+ u8 dst_mac[ETH_ALEN];
>+ u8 src_mac[ETH_ALEN];
>+ __be16 vlan_id;
>+ __be32 dst_ip;
>+ __be32 src_ip;
>+ __be32 dst_ipv6[4];
>+ __be32 src_ipv6[4];
>+ __be16 dst_port;
>+ __be16 src_port;
>+ u32 ip_version;
>+ u8 ip_proto; /* IPPROTO value */
>+ /* L4 port type: src or destination port */
>+#define I40E_CLOUD_FILTER_PORT_SRC 0x01
>+#define I40E_CLOUD_FILTER_PORT_DEST 0x02
>+ u8 port_type;
>+ u32 tenant_id;
>+ u8 flags;
>+#define I40E_CLOUD_TNL_TYPE_NONE 0xff
>+ u8 tunnel_type;
> u16 seid; /* filter control */
> };
>
>@@ -491,6 +536,8 @@ struct i40e_pf {
> #define I40E_FLAG_LINK_DOWN_ON_CLOSE_ENABLED BIT(27)
> #define I40E_FLAG_SOURCE_PRUNING_DISABLED BIT(28)
> #define I40E_FLAG_TC_MQPRIO BIT(29)
>+#define I40E_FLAG_FD_SB_INACTIVE BIT(30)
>+#define I40E_FLAG_FD_SB_TO_CLOUD_FILTER BIT(31)
>
> struct i40e_client_instance *cinst;
> bool stat_offsets_loaded;
>@@ -573,6 +620,8 @@ struct i40e_pf {
> u16 phy_led_val;
>
> u16 override_q_count;
>+ u16 last_sw_conf_flags;
>+ u16 last_sw_conf_valid_flags;
> };
>
> /**
>diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
>index 2e567c2..feb3d42 100644
>--- a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
>+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
>@@ -1392,6 +1392,9 @@ struct i40e_aqc_cloud_filters_element_data {
> struct {
> u8 data[16];
> } v6;
>+ struct {
>+ __le16 data[8];
>+ } raw_v6;
> } ipaddr;
> __le16 flags;
> #define I40E_AQC_ADD_CLOUD_FILTER_SHIFT 0
>diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
>index 9567702..d9c9665 100644
>--- a/drivers/net/ethernet/intel/i40e/i40e_common.c
>+++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
>@@ -5434,5 +5434,194 @@ i40e_add_pinfo_to_list(struct i40e_hw *hw,
>
> status = i40e_aq_write_ppp(hw, (void *)sec, sec->data_end,
> track_id, &offset, &info, NULL);
>+
>+ return status;
>+}
>+
>+/**
>+ * i40e_aq_add_cloud_filters
>+ * @hw: pointer to the hardware structure
>+ * @seid: VSI seid to add cloud filters from
>+ * @filters: Buffer which contains the filters to be added
>+ * @filter_count: number of filters contained in the buffer
>+ *
>+ * Set the cloud filters for a given VSI. The contents of the
>+ * i40e_aqc_cloud_filters_element_data are filled in by the caller
>+ * of the function.
>+ *
>+ **/
>+enum i40e_status_code
>+i40e_aq_add_cloud_filters(struct i40e_hw *hw, u16 seid,
>+ struct i40e_aqc_cloud_filters_element_data *filters,
>+ u8 filter_count)
>+{
>+ struct i40e_aq_desc desc;
>+ struct i40e_aqc_add_remove_cloud_filters *cmd =
>+ (struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
>+ enum i40e_status_code status;
>+ u16 buff_len;
>+
>+ i40e_fill_default_direct_cmd_desc(&desc,
>+ i40e_aqc_opc_add_cloud_filters);
>+
>+ buff_len = filter_count * sizeof(*filters);
>+ desc.datalen = cpu_to_le16(buff_len);
>+ desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
>+ cmd->num_filters = filter_count;
>+ cmd->seid = cpu_to_le16(seid);
>+
>+ status = i40e_asq_send_command(hw, &desc, filters, buff_len, NULL);
>+
>+ return status;
>+}
>+
>+/**
>+ * i40e_aq_add_cloud_filters_bb
>+ * @hw: pointer to the hardware structure
>+ * @seid: VSI seid to add cloud filters from
>+ * @filters: Buffer which contains the filters in big buffer to be added
>+ * @filter_count: number of filters contained in the buffer
>+ *
>+ * Set the big buffer cloud filters for a given VSI. The contents of the
>+ * i40e_aqc_cloud_filters_element_bb are filled in by the caller of the
>+ * function.
>+ *
>+ **/
>+i40e_status
>+i40e_aq_add_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
>+ struct i40e_aqc_cloud_filters_element_bb *filters,
>+ u8 filter_count)
>+{
>+ struct i40e_aq_desc desc;
>+ struct i40e_aqc_add_remove_cloud_filters *cmd =
>+ (struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
>+ i40e_status status;
>+ u16 buff_len;
>+ int i;
>+
>+ i40e_fill_default_direct_cmd_desc(&desc,
>+ i40e_aqc_opc_add_cloud_filters);
>+
>+ buff_len = filter_count * sizeof(*filters);
>+ desc.datalen = cpu_to_le16(buff_len);
>+ desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
>+ cmd->num_filters = filter_count;
>+ cmd->seid = cpu_to_le16(seid);
>+ cmd->big_buffer_flag = I40E_AQC_ADD_CLOUD_CMD_BB;
>+
>+ for (i = 0; i < filter_count; i++) {
>+ u16 tnl_type;
>+ u32 ti;
>+
>+ tnl_type = (le16_to_cpu(filters[i].element.flags) &
>+ I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK) >>
>+ I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT;
>+
>+ /* For Geneve, the VNI should be placed in offset shifted by a
>+ * byte than the offset for the Tenant ID for rest of the
>+ * tunnels.
>+ */
>+ if (tnl_type == I40E_AQC_ADD_CLOUD_TNL_TYPE_GENEVE) {
>+ ti = le32_to_cpu(filters[i].element.tenant_id);
>+ filters[i].element.tenant_id = cpu_to_le32(ti << 8);
>+ }
>+ }
>+
>+ status = i40e_asq_send_command(hw, &desc, filters, buff_len, NULL);
>+
>+ return status;
>+}
>+
>+/**
>+ * i40e_aq_rem_cloud_filters
>+ * @hw: pointer to the hardware structure
>+ * @seid: VSI seid to remove cloud filters from
>+ * @filters: Buffer which contains the filters to be removed
>+ * @filter_count: number of filters contained in the buffer
>+ *
>+ * Remove the cloud filters for a given VSI. The contents of the
>+ * i40e_aqc_cloud_filters_element_data are filled in by the caller
>+ * of the function.
>+ *
>+ **/
>+enum i40e_status_code
>+i40e_aq_rem_cloud_filters(struct i40e_hw *hw, u16 seid,
>+ struct i40e_aqc_cloud_filters_element_data *filters,
>+ u8 filter_count)
>+{
>+ struct i40e_aq_desc desc;
>+ struct i40e_aqc_add_remove_cloud_filters *cmd =
>+ (struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
>+ enum i40e_status_code status;
>+ u16 buff_len;
>+
>+ i40e_fill_default_direct_cmd_desc(&desc,
>+ i40e_aqc_opc_remove_cloud_filters);
>+
>+ buff_len = filter_count * sizeof(*filters);
>+ desc.datalen = cpu_to_le16(buff_len);
>+ desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
>+ cmd->num_filters = filter_count;
>+ cmd->seid = cpu_to_le16(seid);
>+
>+ status = i40e_asq_send_command(hw, &desc, filters, buff_len, NULL);
>+
>+ return status;
>+}
>+
>+/**
>+ * i40e_aq_rem_cloud_filters_bb
>+ * @hw: pointer to the hardware structure
>+ * @seid: VSI seid to remove cloud filters from
>+ * @filters: Buffer which contains the filters in big buffer to be removed
>+ * @filter_count: number of filters contained in the buffer
>+ *
>+ * Remove the big buffer cloud filters for a given VSI. The contents of the
>+ * i40e_aqc_cloud_filters_element_bb are filled in by the caller of the
>+ * function.
>+ *
>+ **/
>+i40e_status
>+i40e_aq_rem_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
>+ struct i40e_aqc_cloud_filters_element_bb *filters,
>+ u8 filter_count)
>+{
>+ struct i40e_aq_desc desc;
>+ struct i40e_aqc_add_remove_cloud_filters *cmd =
>+ (struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
>+ i40e_status status;
>+ u16 buff_len;
>+ int i;
>+
>+ i40e_fill_default_direct_cmd_desc(&desc,
>+ i40e_aqc_opc_remove_cloud_filters);
>+
>+ buff_len = filter_count * sizeof(*filters);
>+ desc.datalen = cpu_to_le16(buff_len);
>+ desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
>+ cmd->num_filters = filter_count;
>+ cmd->seid = cpu_to_le16(seid);
>+ cmd->big_buffer_flag = I40E_AQC_ADD_CLOUD_CMD_BB;
>+
>+ for (i = 0; i < filter_count; i++) {
>+ u16 tnl_type;
>+ u32 ti;
>+
>+ tnl_type = (le16_to_cpu(filters[i].element.flags) &
>+ I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK) >>
>+ I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT;
>+
>+ /* For Geneve, the VNI should be placed in offset shifted by a
>+ * byte than the offset for the Tenant ID for rest of the
>+ * tunnels.
>+ */
>+ if (tnl_type == I40E_AQC_ADD_CLOUD_TNL_TYPE_GENEVE) {
>+ ti = le32_to_cpu(filters[i].element.tenant_id);
>+ filters[i].element.tenant_id = cpu_to_le32(ti << 8);
>+ }
>+ }
>+
>+ status = i40e_asq_send_command(hw, &desc, filters, buff_len, NULL);
>+
> return status;
> }
>diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
>index afcf08a..96ee608 100644
>--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
>+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
>@@ -69,6 +69,15 @@ static int i40e_reset(struct i40e_pf *pf);
> static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired);
> static void i40e_fdir_sb_setup(struct i40e_pf *pf);
> static int i40e_veb_get_bw_info(struct i40e_veb *veb);
>+static int i40e_add_del_cloud_filter(struct i40e_vsi *vsi,
>+ struct i40e_cloud_filter *filter,
>+ bool add);
>+static int i40e_add_del_cloud_filter_big_buf(struct i40e_vsi *vsi,
>+ struct i40e_cloud_filter *filter,
>+ bool add);
>+static int i40e_get_capabilities(struct i40e_pf *pf,
>+ enum i40e_admin_queue_opc list_type);
>+
>
> /* i40e_pci_tbl - PCI Device ID Table
> *
>@@ -5478,7 +5487,11 @@ int i40e_set_bw_limit(struct i40e_vsi *vsi, u16 seid, u64 max_tx_rate)
> **/
> static void i40e_remove_queue_channels(struct i40e_vsi *vsi)
> {
>+ enum i40e_admin_queue_err last_aq_status;
>+ struct i40e_cloud_filter *cfilter;
> struct i40e_channel *ch, *ch_tmp;
>+ struct i40e_pf *pf = vsi->back;
>+ struct hlist_node *node;
> int ret, i;
>
> /* Reset rss size that was stored when reconfiguring rss for
>@@ -5519,6 +5532,29 @@ static void i40e_remove_queue_channels(struct i40e_vsi *vsi)
> "Failed to reset tx rate for ch->seid %u\n",
> ch->seid);
>
>+ /* delete cloud filters associated with this channel */
>+ hlist_for_each_entry_safe(cfilter, node,
>+ &pf->cloud_filter_list, cloud_node) {
>+ if (cfilter->seid != ch->seid)
>+ continue;
>+
>+ hash_del(&cfilter->cloud_node);
>+ if (cfilter->dst_port)
>+ ret = i40e_add_del_cloud_filter_big_buf(vsi,
>+ cfilter,
>+ false);
>+ else
>+ ret = i40e_add_del_cloud_filter(vsi, cfilter,
>+ false);
>+ last_aq_status = pf->hw.aq.asq_last_status;
>+ if (ret)
>+ dev_info(&pf->pdev->dev,
>+ "Failed to delete cloud filter, err %s aq_err %s\n",
>+ i40e_stat_str(&pf->hw, ret),
>+ i40e_aq_str(&pf->hw, last_aq_status));
>+ kfree(cfilter);
>+ }
>+
> /* delete VSI from FW */
> ret = i40e_aq_delete_element(&vsi->back->hw, ch->seid,
> NULL);
>@@ -5970,6 +6006,74 @@ static bool i40e_setup_channel(struct i40e_pf *pf, struct i40e_vsi *vsi,
> }
>
> /**
>+ * i40e_validate_and_set_switch_mode - sets up switch mode correctly
>+ * @vsi: ptr to VSI which has PF backing
>+ * @l4type: true for TCP ond false for UDP
>+ * @port_type: true if port is destination and false if port is source
>+ *
>+ * Sets up switch mode correctly if it needs to be changed and perform
>+ * what are allowed modes.
>+ **/
>+static int i40e_validate_and_set_switch_mode(struct i40e_vsi *vsi, bool l4type,
>+ bool port_type)
>+{
>+ u8 mode;
>+ struct i40e_pf *pf = vsi->back;
>+ struct i40e_hw *hw = &pf->hw;
>+ int ret;
>+
>+ ret = i40e_get_capabilities(pf, i40e_aqc_opc_list_dev_capabilities);
>+ if (ret)
>+ return -EINVAL;
>+
>+ if (hw->dev_caps.switch_mode) {
>+ /* if switch mode is set, support mode2 (non-tunneled for
>+ * cloud filter) for now
>+ */
>+ u32 switch_mode = hw->dev_caps.switch_mode &
>+ I40E_SWITCH_MODE_MASK;
>+ if (switch_mode >= I40E_NVM_IMAGE_TYPE_MODE1) {
>+ if (switch_mode == I40E_NVM_IMAGE_TYPE_MODE2)
>+ return 0;
>+ dev_err(&pf->pdev->dev,
>+ "Invalid switch_mode (%d), only non-tunneled mode for cloud filter is supported\n",
>+ hw->dev_caps.switch_mode);
>+ return -EINVAL;
>+ }
>+ }
>+
>+ /* port_type: true for destination port and false for source port
>+ * For now, supports only destination port type
>+ */
>+ if (!port_type) {
>+ dev_err(&pf->pdev->dev, "src port type not supported\n");
>+ return -EINVAL;
>+ }
>+
>+ /* Set Bit 7 to be valid */
>+ mode = I40E_AQ_SET_SWITCH_BIT7_VALID;
>+
>+ /* Set L4type to both TCP and UDP support */
>+ mode |= I40E_AQ_SET_SWITCH_L4_TYPE_BOTH;
>+
>+ /* Set cloud filter mode */
>+ mode |= I40E_AQ_SET_SWITCH_MODE_NON_TUNNEL;
>+
>+ /* Prep mode field for set_switch_config */
>+ ret = i40e_aq_set_switch_config(hw, pf->last_sw_conf_flags,
>+ pf->last_sw_conf_valid_flags,
>+ mode, NULL);
>+ if (ret && hw->aq.asq_last_status != I40E_AQ_RC_ESRCH)
>+ dev_err(&pf->pdev->dev,
>+ "couldn't set switch config bits, err %s aq_err %s\n",
>+ i40e_stat_str(hw, ret),
>+ i40e_aq_str(hw,
>+ hw->aq.asq_last_status));
>+
>+ return ret;
>+}
>+
>+/**
> * i40e_create_queue_channel - function to create channel
> * @vsi: VSI to be configured
> * @ch: ptr to channel (it contains channel specific params)
>@@ -6735,13 +6839,726 @@ static int i40e_setup_tc(struct net_device *netdev, void *type_data)
> return ret;
> }
>
>+/**
>+ * i40e_set_cld_element - sets cloud filter element data
>+ * @filter: cloud filter rule
>+ * @cld: ptr to cloud filter element data
>+ *
>+ * This is helper function to copy data into cloud filter element
>+ **/
>+static inline void
>+i40e_set_cld_element(struct i40e_cloud_filter *filter,
>+ struct i40e_aqc_cloud_filters_element_data *cld)
>+{
>+ int i, j;
>+ u32 ipa;
>+
>+ memset(cld, 0, sizeof(*cld));
>+ ether_addr_copy(cld->outer_mac, filter->dst_mac);
>+ ether_addr_copy(cld->inner_mac, filter->src_mac);
>+
>+ if (filter->ip_version == IPV6_VERSION) {
>+#define IPV6_MAX_INDEX (ARRAY_SIZE(filter->dst_ipv6) - 1)
>+ for (i = 0, j = 0; i < 4; i++, j += 2) {
>+ ipa = be32_to_cpu(filter->dst_ipv6[IPV6_MAX_INDEX - i]);
>+ ipa = cpu_to_le32(ipa);
>+ memcpy(&cld->ipaddr.raw_v6.data[j], &ipa, 4);
>+ }
>+ } else {
>+ ipa = be32_to_cpu(filter->dst_ip);
>+ memcpy(&cld->ipaddr.v4.data, &ipa, 4);
>+ }
>+
>+ cld->inner_vlan = cpu_to_le16(ntohs(filter->vlan_id));
>+
>+ /* tenant_id is not supported by FW now, once the support is enabled
>+ * fill the cld->tenant_id with cpu_to_le32(filter->tenant_id)
>+ */
>+ if (filter->tenant_id)
>+ return;
>+}
>+
>+/**
>+ * i40e_add_del_cloud_filter - Add/del cloud filter
>+ * @vsi: pointer to VSI
>+ * @filter: cloud filter rule
>+ * @add: if true, add, if false, delete
>+ *
>+ * Add or delete a cloud filter for a specific flow spec.
>+ * Returns 0 if the filter were successfully added.
>+ **/
>+static int i40e_add_del_cloud_filter(struct i40e_vsi *vsi,
>+ struct i40e_cloud_filter *filter, bool add)
>+{
>+ struct i40e_aqc_cloud_filters_element_data cld_filter;
>+ struct i40e_pf *pf = vsi->back;
>+ int ret;
>+ static const u16 flag_table[128] = {
>+ [I40E_CLOUD_FILTER_FLAGS_OMAC] =
>+ I40E_AQC_ADD_CLOUD_FILTER_OMAC,
>+ [I40E_CLOUD_FILTER_FLAGS_IMAC] =
>+ I40E_AQC_ADD_CLOUD_FILTER_IMAC,
>+ [I40E_CLOUD_FILTER_FLAGS_IMAC_IVLAN] =
>+ I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN,
>+ [I40E_CLOUD_FILTER_FLAGS_IMAC_TEN_ID] =
>+ I40E_AQC_ADD_CLOUD_FILTER_IMAC_TEN_ID,
>+ [I40E_CLOUD_FILTER_FLAGS_OMAC_TEN_ID_IMAC] =
>+ I40E_AQC_ADD_CLOUD_FILTER_OMAC_TEN_ID_IMAC,
>+ [I40E_CLOUD_FILTER_FLAGS_IMAC_IVLAN_TEN_ID] =
>+ I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN_TEN_ID,
>+ [I40E_CLOUD_FILTER_FLAGS_IIP] =
>+ I40E_AQC_ADD_CLOUD_FILTER_IIP,
>+ };
>+
>+ if (filter->flags >= ARRAY_SIZE(flag_table))
>+ return I40E_ERR_CONFIG;
>+
>+ /* copy element needed to add cloud filter from filter */
>+ i40e_set_cld_element(filter, &cld_filter);
>+
>+ if (filter->tunnel_type != I40E_CLOUD_TNL_TYPE_NONE)
>+ cld_filter.flags = cpu_to_le16(filter->tunnel_type <<
>+ I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT);
>+
>+ if (filter->ip_version == IPV6_VERSION)
>+ cld_filter.flags |= cpu_to_le16(flag_table[filter->flags] |
>+ I40E_AQC_ADD_CLOUD_FLAGS_IPV6);
>+ else
>+ cld_filter.flags |= cpu_to_le16(flag_table[filter->flags] |
>+ I40E_AQC_ADD_CLOUD_FLAGS_IPV4);
>+
>+ if (add)
>+ ret = i40e_aq_add_cloud_filters(&pf->hw, filter->seid,
>+ &cld_filter, 1);
>+ else
>+ ret = i40e_aq_rem_cloud_filters(&pf->hw, filter->seid,
>+ &cld_filter, 1);
>+ if (ret)
>+ dev_dbg(&pf->pdev->dev,
>+ "Failed to %s cloud filter using l4 port %u, err %d aq_err %d\n",
>+ add ? "add" : "delete", filter->dst_port, ret,
>+ pf->hw.aq.asq_last_status);
>+ else
>+ dev_info(&pf->pdev->dev,
>+ "%s cloud filter for VSI: %d\n",
>+ add ? "Added" : "Deleted", filter->seid);
>+ return ret;
>+}
>+
>+/**
>+ * i40e_add_del_cloud_filter_big_buf - Add/del cloud filter using big_buf
>+ * @vsi: pointer to VSI
>+ * @filter: cloud filter rule
>+ * @add: if true, add, if false, delete
>+ *
>+ * Add or delete a cloud filter for a specific flow spec using big buffer.
>+ * Returns 0 if the filter were successfully added.
>+ **/
>+static int i40e_add_del_cloud_filter_big_buf(struct i40e_vsi *vsi,
>+ struct i40e_cloud_filter *filter,
>+ bool add)
>+{
>+ struct i40e_aqc_cloud_filters_element_bb cld_filter;
>+ struct i40e_pf *pf = vsi->back;
>+ int ret;
>+
>+ /* Both (Outer/Inner) valid mac_addr are not supported */
>+ if (is_valid_ether_addr(filter->dst_mac) &&
>+ is_valid_ether_addr(filter->src_mac))
>+ return -EINVAL;
>+
>+ /* Make sure port is specified, otherwise bail out, for channel
>+ * specific cloud filter needs 'L4 port' to be non-zero
>+ */
>+ if (!filter->dst_port)
>+ return -EINVAL;
>+
>+ /* adding filter using src_port/src_ip is not supported at this stage */
>+ if (filter->src_port || filter->src_ip ||
>+ !ipv6_addr_any((struct in6_addr *)&filter->src_ipv6))
>+ return -EINVAL;
>+
>+ /* copy element needed to add cloud filter from filter */
>+ i40e_set_cld_element(filter, &cld_filter.element);
>+
>+ if (is_valid_ether_addr(filter->dst_mac) ||
>+ is_valid_ether_addr(filter->src_mac) ||
>+ is_multicast_ether_addr(filter->dst_mac) ||
>+ is_multicast_ether_addr(filter->src_mac)) {
>+ /* MAC + IP : unsupported mode */
>+ if (filter->dst_ip)
>+ return -EINVAL;
>+
>+ /* since we validated that L4 port must be valid before
>+ * we get here, start with respective "flags" value
>+ * and update if vlan is present or not
>+ */
>+ cld_filter.element.flags =
>+ cpu_to_le16(I40E_AQC_ADD_CLOUD_FILTER_MAC_PORT);
>+
>+ if (filter->vlan_id) {
>+ cld_filter.element.flags =
>+ cpu_to_le16(I40E_AQC_ADD_CLOUD_FILTER_MAC_VLAN_PORT);
>+ }
>+
>+ } else if (filter->dst_ip || filter->ip_version == IPV6_VERSION) {
>+ cld_filter.element.flags =
>+ cpu_to_le16(I40E_AQC_ADD_CLOUD_FILTER_IP_PORT);
>+ if (filter->ip_version == IPV6_VERSION)
>+ cld_filter.element.flags |=
>+ cpu_to_le16(I40E_AQC_ADD_CLOUD_FLAGS_IPV6);
>+ else
>+ cld_filter.element.flags |=
>+ cpu_to_le16(I40E_AQC_ADD_CLOUD_FLAGS_IPV4);
>+ } else {
>+ dev_err(&pf->pdev->dev,
>+ "either mac or ip has to be valid for cloud filter\n");
>+ return -EINVAL;
>+ }
>+
>+ /* Now copy L4 port in Byte 6..7 in general fields */
>+ cld_filter.general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X16_WORD0] =
>+ be16_to_cpu(filter->dst_port);
>+
>+ if (add) {
>+ bool proto_type, port_type;
>+
>+ proto_type = (filter->ip_proto == IPPROTO_TCP) ? true : false;
>+ port_type = (filter->port_type & I40E_CLOUD_FILTER_PORT_DEST) ?
>+ true : false;
>+
>+ /* For now, src port based cloud filter for channel is not
>+ * supported
>+ */
>+ if (!port_type) {
>+ dev_err(&pf->pdev->dev,
>+ "unsupported port type (src port)\n");
>+ return -EOPNOTSUPP;
>+ }
>+
>+ /* Validate current device switch mode, change if necessary */
>+ ret = i40e_validate_and_set_switch_mode(vsi, proto_type,
>+ port_type);
>+ if (ret) {
>+ dev_err(&pf->pdev->dev,
>+ "failed to set switch mode, ret %d\n",
>+ ret);
>+ return ret;
>+ }
>+
>+ ret = i40e_aq_add_cloud_filters_bb(&pf->hw, filter->seid,
>+ &cld_filter, 1);
>+ } else {
>+ ret = i40e_aq_rem_cloud_filters_bb(&pf->hw, filter->seid,
>+ &cld_filter, 1);
>+ }
>+
>+ if (ret)
>+ dev_dbg(&pf->pdev->dev,
>+ "Failed to %s cloud filter(big buffer) err %d aq_err %d\n",
>+ add ? "add" : "delete", ret, pf->hw.aq.asq_last_status);
>+ else
>+ dev_info(&pf->pdev->dev,
>+ "%s cloud filter for VSI: %d, L4 port: %d\n",
>+ add ? "add" : "delete", filter->seid,
>+ ntohs(filter->dst_port));
>+ return ret;
>+}
>+
>+/**
>+ * i40e_parse_cls_flower - Parse tc flower filters provided by kernel
>+ * @vsi: Pointer to VSI
>+ * @cls_flower: Pointer to struct tc_cls_flower_offload
>+ * @filter: Pointer to cloud filter structure
>+ *
>+ **/
>+static int i40e_parse_cls_flower(struct i40e_vsi *vsi,
>+ struct tc_cls_flower_offload *f,
>+ struct i40e_cloud_filter *filter)
>+{
>+ struct i40e_pf *pf = vsi->back;
>+ u16 addr_type = 0;
>+ u8 field_flags = 0;
>+
>+ if (f->dissector->used_keys &
>+ ~(BIT(FLOW_DISSECTOR_KEY_CONTROL) |
>+ BIT(FLOW_DISSECTOR_KEY_BASIC) |
>+ BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS) |
>+ BIT(FLOW_DISSECTOR_KEY_VLAN) |
>+ BIT(FLOW_DISSECTOR_KEY_IPV4_ADDRS) |
>+ BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS) |
>+ BIT(FLOW_DISSECTOR_KEY_PORTS) |
>+ BIT(FLOW_DISSECTOR_KEY_ENC_KEYID))) {
>+ dev_err(&pf->pdev->dev, "Unsupported key used: 0x%x\n",
>+ f->dissector->used_keys);
>+ return -EOPNOTSUPP;
>+ }
>+
>+ if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_ENC_KEYID)) {
>+ struct flow_dissector_key_keyid *key =
>+ skb_flow_dissector_target(f->dissector,
>+ FLOW_DISSECTOR_KEY_ENC_KEYID,
>+ f->key);
>+
>+ struct flow_dissector_key_keyid *mask =
>+ skb_flow_dissector_target(f->dissector,
>+ FLOW_DISSECTOR_KEY_ENC_KEYID,
>+ f->mask);
>+
>+ if (mask->keyid != 0)
>+ field_flags |= I40E_CLOUD_FIELD_TEN_ID;
>+
>+ filter->tenant_id = be32_to_cpu(key->keyid);
>+ }
>+
>+ if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
>+ struct flow_dissector_key_basic *key =
>+ skb_flow_dissector_target(f->dissector,
>+ FLOW_DISSECTOR_KEY_BASIC,
>+ f->key);
>+
>+ filter->ip_proto = key->ip_proto;
>+ }
>+
>+ if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
>+ struct flow_dissector_key_eth_addrs *key =
>+ skb_flow_dissector_target(f->dissector,
>+ FLOW_DISSECTOR_KEY_ETH_ADDRS,
>+ f->key);
>+
>+ struct flow_dissector_key_eth_addrs *mask =
>+ skb_flow_dissector_target(f->dissector,
>+ FLOW_DISSECTOR_KEY_ETH_ADDRS,
>+ f->mask);
>+
>+ /* use is_broadcast and is_zero to check for all 0xf or 0 */
>+ if (!is_zero_ether_addr(mask->dst)) {
>+ if (is_broadcast_ether_addr(mask->dst)) {
>+ field_flags |= I40E_CLOUD_FIELD_OMAC;
>+ } else {
>+ dev_err(&pf->pdev->dev, "Bad ether dest mask %pM\n",
>+ mask->dst);
>+ return I40E_ERR_CONFIG;
>+ }
>+ }
>+
>+ if (!is_zero_ether_addr(mask->src)) {
>+ if (is_broadcast_ether_addr(mask->src)) {
>+ field_flags |= I40E_CLOUD_FIELD_IMAC;
>+ } else {
>+ dev_err(&pf->pdev->dev, "Bad ether src mask %pM\n",
>+ mask->src);
>+ return I40E_ERR_CONFIG;
>+ }
>+ }
>+ ether_addr_copy(filter->dst_mac, key->dst);
>+ ether_addr_copy(filter->src_mac, key->src);
>+ }
>+
>+ if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_VLAN)) {
>+ struct flow_dissector_key_vlan *key =
>+ skb_flow_dissector_target(f->dissector,
>+ FLOW_DISSECTOR_KEY_VLAN,
>+ f->key);
>+ struct flow_dissector_key_vlan *mask =
>+ skb_flow_dissector_target(f->dissector,
>+ FLOW_DISSECTOR_KEY_VLAN,
>+ f->mask);
>+
>+ if (mask->vlan_id) {
>+ if (mask->vlan_id == VLAN_VID_MASK) {
>+ field_flags |= I40E_CLOUD_FIELD_IVLAN;
>+
>+ } else {
>+ dev_err(&pf->pdev->dev, "Bad vlan mask 0x%04x\n",
>+ mask->vlan_id);
>+ return I40E_ERR_CONFIG;
>+ }
>+ }
>+
>+ filter->vlan_id = cpu_to_be16(key->vlan_id);
>+ }
>+
>+ if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_CONTROL)) {
>+ struct flow_dissector_key_control *key =
>+ skb_flow_dissector_target(f->dissector,
>+ FLOW_DISSECTOR_KEY_CONTROL,
>+ f->key);
>+
>+ addr_type = key->addr_type;
>+ }
>+
>+ if (addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) {
>+ struct flow_dissector_key_ipv4_addrs *key =
>+ skb_flow_dissector_target(f->dissector,
>+ FLOW_DISSECTOR_KEY_IPV4_ADDRS,
>+ f->key);
>+ struct flow_dissector_key_ipv4_addrs *mask =
>+ skb_flow_dissector_target(f->dissector,
>+ FLOW_DISSECTOR_KEY_IPV4_ADDRS,
>+ f->mask);
>+
>+ if (mask->dst) {
>+ if (mask->dst == cpu_to_be32(0xffffffff)) {
>+ field_flags |= I40E_CLOUD_FIELD_IIP;
>+ } else {
>+ dev_err(&pf->pdev->dev, "Bad ip dst mask 0x%08x\n",
>+ be32_to_cpu(mask->dst));
>+ return I40E_ERR_CONFIG;
>+ }
>+ }
>+
>+ if (mask->src) {
>+ if (mask->src == cpu_to_be32(0xffffffff)) {
>+ field_flags |= I40E_CLOUD_FIELD_IIP;
>+ } else {
>+ dev_err(&pf->pdev->dev, "Bad ip src mask 0x%08x\n",
>+ be32_to_cpu(mask->dst));
>+ return I40E_ERR_CONFIG;
>+ }
>+ }
>+
>+ if (field_flags & I40E_CLOUD_FIELD_TEN_ID) {
>+ dev_err(&pf->pdev->dev, "Tenant id not allowed for ip filter\n");
>+ return I40E_ERR_CONFIG;
>+ }
>+ filter->dst_ip = key->dst;
>+ filter->src_ip = key->src;
>+ filter->ip_version = IPV4_VERSION;
>+ }
>+
>+ if (addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) {
>+ struct flow_dissector_key_ipv6_addrs *key =
>+ skb_flow_dissector_target(f->dissector,
>+ FLOW_DISSECTOR_KEY_IPV6_ADDRS,
>+ f->key);
>+ struct flow_dissector_key_ipv6_addrs *mask =
>+ skb_flow_dissector_target(f->dissector,
>+ FLOW_DISSECTOR_KEY_IPV6_ADDRS,
>+ f->mask);
>+
>+ /* src and dest IPV6 address should not be LOOPBACK
>+ * (0:0:0:0:0:0:0:1), which can be represented as ::1
>+ */
>+ if (ipv6_addr_loopback(&key->dst) ||
>+ ipv6_addr_loopback(&key->src)) {
>+ dev_err(&pf->pdev->dev,
>+ "Bad ipv6, addr is LOOPBACK\n");
>+ return I40E_ERR_CONFIG;
>+ }
>+ if (!ipv6_addr_any(&mask->dst) || !ipv6_addr_any(&mask->src))
>+ field_flags |= I40E_CLOUD_FIELD_IIP;
>+
>+ memcpy(&filter->src_ipv6, &key->src.s6_addr32,
>+ sizeof(filter->src_ipv6));
>+ memcpy(&filter->dst_ipv6, &key->dst.s6_addr32,
>+ sizeof(filter->dst_ipv6));
>+
>+ /* mark it as IPv6 filter, to be used later */
>+ filter->ip_version = IPV6_VERSION;
>+ }
>+
>+ if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_PORTS)) {
>+ struct flow_dissector_key_ports *key =
>+ skb_flow_dissector_target(f->dissector,
>+ FLOW_DISSECTOR_KEY_PORTS,
>+ f->key);
>+ struct flow_dissector_key_ports *mask =
>+ skb_flow_dissector_target(f->dissector,
>+ FLOW_DISSECTOR_KEY_PORTS,
>+ f->mask);
>+
>+ if (mask->src) {
>+ if (mask->src == cpu_to_be16(0xffff)) {
>+ field_flags |= I40E_CLOUD_FIELD_IIP;
>+ } else {
>+ dev_err(&pf->pdev->dev, "Bad src port mask 0x%04x\n",
>+ be16_to_cpu(mask->src));
>+ return I40E_ERR_CONFIG;
>+ }
>+ }
>+
>+ if (mask->dst) {
>+ if (mask->dst == cpu_to_be16(0xffff)) {
>+ field_flags |= I40E_CLOUD_FIELD_IIP;
>+ } else {
>+ dev_err(&pf->pdev->dev, "Bad dst port mask 0x%04x\n",
>+ be16_to_cpu(mask->dst));
>+ return I40E_ERR_CONFIG;
>+ }
>+ }
>+
>+ filter->dst_port = key->dst;
>+ filter->src_port = key->src;
>+
>+ /* For now, only supports destination port*/
>+ filter->port_type |= I40E_CLOUD_FILTER_PORT_DEST;
>+
>+ switch (filter->ip_proto) {
>+ case IPPROTO_TCP:
>+ case IPPROTO_UDP:
>+ break;
>+ default:
>+ dev_err(&pf->pdev->dev,
>+ "Only UDP and TCP transport are supported\n");
>+ return -EINVAL;
>+ }
>+ }
>+ filter->flags = field_flags;
>+ return 0;
>+}
>+
>+/**
>+ * i40e_handle_redirect_action: Forward to a traffic class on the device
>+ * @vsi: Pointer to VSI
>+ * @ifindex: ifindex of the device to forwared to
>+ * @tc: traffic class index on the device
>+ * @filter: Pointer to cloud filter structure
>+ *
>+ **/
>+static int i40e_handle_redirect_action(struct i40e_vsi *vsi, int ifindex, u8 tc,
>+ struct i40e_cloud_filter *filter)
>+{
>+ struct i40e_channel *ch, *ch_tmp;
>+
>+ /* redirect to a traffic class on the same device */
>+ if (vsi->netdev->ifindex == ifindex) {
>+ if (tc == 0) {
>+ filter->seid = vsi->seid;
>+ return 0;
>+ } else if (vsi->tc_config.enabled_tc & BIT(tc)) {
>+ if (!filter->dst_port) {
>+ dev_err(&vsi->back->pdev->dev,
>+ "Specify destination port to redirect to traffic class that is not default\n");
>+ return -EINVAL;
>+ }
>+ if (list_empty(&vsi->ch_list))
>+ return -EINVAL;
>+ list_for_each_entry_safe(ch, ch_tmp, &vsi->ch_list,
>+ list) {
>+ if (ch->seid == vsi->tc_seid_map[tc])
>+ filter->seid = ch->seid;
>+ }
>+ return 0;
>+ }
>+ }
>+ return -EINVAL;
>+}
>+
>+/**
>+ * i40e_parse_tc_actions - Parse tc actions
>+ * @vsi: Pointer to VSI
>+ * @cls_flower: Pointer to struct tc_cls_flower_offload
>+ * @filter: Pointer to cloud filter structure
>+ *
>+ **/
>+static int i40e_parse_tc_actions(struct i40e_vsi *vsi, struct tcf_exts *exts,
>+ struct i40e_cloud_filter *filter)
>+{
>+ const struct tc_action *a;
>+ LIST_HEAD(actions);
>+ int err;
>+
>+ if (!tcf_exts_has_actions(exts))
>+ return -EINVAL;
>+
>+ tcf_exts_to_list(exts, &actions);
>+ list_for_each_entry(a, &actions, list) {
>+ /* Drop action */
>+ if (is_tcf_gact_shot(a)) {
>+ dev_err(&vsi->back->pdev->dev,
>+ "Cloud filters do not support the drop action.\n");
>+ return -EOPNOTSUPP;
>+ }
>+
>+ /* Redirect to a traffic class on the same device */
>+ if (!is_tcf_mirred_egress_redirect(a) && is_tcf_mirred_tc(a)) {
>+ int ifindex = tcf_mirred_ifindex(a);
>+ u8 tc = tcf_mirred_tc(a);
>+
>+ err = i40e_handle_redirect_action(vsi, ifindex, tc,
>+ filter);
>+ if (err == 0)
>+ return err;
>+ }
>+ }
>+ return -EINVAL;
>+}
>+
>+/**
>+ * i40e_configure_clsflower - Configure tc flower filters
>+ * @vsi: Pointer to VSI
>+ * @cls_flower: Pointer to struct tc_cls_flower_offload
>+ *
>+ **/
>+static int i40e_configure_clsflower(struct i40e_vsi *vsi,
>+ struct tc_cls_flower_offload *cls_flower)
>+{
>+ struct i40e_cloud_filter *filter = NULL;
>+ struct i40e_pf *pf = vsi->back;
>+ int err = 0;
>+
>+ if (test_bit(__I40E_RESET_RECOVERY_PENDING, pf->state) ||
>+ test_bit(__I40E_RESET_INTR_RECEIVED, pf->state))
>+ return -EBUSY;
>+
>+ if (pf->fdir_pf_active_filters ||
>+ (!hlist_empty(&pf->fdir_filter_list))) {
>+ dev_err(&vsi->back->pdev->dev,
>+ "Flow Director Sideband filters exists, turn ntuple off to configure cloud filters\n");
>+ return -EINVAL;
>+ }
>+
>+ if (vsi->back->flags & I40E_FLAG_FD_SB_ENABLED) {
>+ dev_err(&vsi->back->pdev->dev,
>+ "Disable Flow Director Sideband, configuring Cloud filters via tc-flower\n");
>+ vsi->back->flags &= ~I40E_FLAG_FD_SB_ENABLED;
>+ vsi->back->flags |= I40E_FLAG_FD_SB_TO_CLOUD_FILTER;
>+ }
>+
>+ filter = kzalloc(sizeof(*filter), GFP_KERNEL);
>+ if (!filter)
>+ return -ENOMEM;
>+
>+ filter->cookie = cls_flower->cookie;
>+
>+ err = i40e_parse_cls_flower(vsi, cls_flower, filter);
>+ if (err < 0)
>+ goto err;
>+
>+ err = i40e_parse_tc_actions(vsi, cls_flower->exts, filter);
>+ if (err < 0)
>+ goto err;
>+
>+ /* Add cloud filter */
>+ if (filter->dst_port)
>+ err = i40e_add_del_cloud_filter_big_buf(vsi, filter, true);
>+ else
>+ err = i40e_add_del_cloud_filter(vsi, filter, true);
>+
>+ if (err) {
>+ dev_err(&pf->pdev->dev,
>+ "Failed to add cloud filter, err %s\n",
>+ i40e_stat_str(&pf->hw, err));
>+ err = i40e_aq_rc_to_posix(err, pf->hw.aq.asq_last_status);
>+ goto err;
>+ }
>+
>+ /* add filter to the ordered list */
>+ INIT_HLIST_NODE(&filter->cloud_node);
>+
>+ hlist_add_head(&filter->cloud_node, &pf->cloud_filter_list);
>+
>+ pf->num_cloud_filters++;
>+
>+ return err;
>+err:
>+ kfree(filter);
>+ return err;
>+}
>+
>+/**
>+ * i40e_find_cloud_filter - Find the could filter in the list
>+ * @vsi: Pointer to VSI
>+ * @cookie: filter specific cookie
>+ *
>+ **/
>+static struct i40e_cloud_filter *i40e_find_cloud_filter(struct i40e_vsi *vsi,
>+ unsigned long *cookie)
>+{
>+ struct i40e_cloud_filter *filter = NULL;
>+ struct hlist_node *node2;
>+
>+ hlist_for_each_entry_safe(filter, node2,
>+ &vsi->back->cloud_filter_list, cloud_node)
>+ if (!memcmp(cookie, &filter->cookie, sizeof(filter->cookie)))
>+ return filter;
>+ return NULL;
>+}
>+
>+/**
>+ * i40e_delete_clsflower - Remove tc flower filters
>+ * @vsi: Pointer to VSI
>+ * @cls_flower: Pointer to struct tc_cls_flower_offload
>+ *
>+ **/
>+static int i40e_delete_clsflower(struct i40e_vsi *vsi,
>+ struct tc_cls_flower_offload *cls_flower)
>+{
>+ struct i40e_cloud_filter *filter = NULL;
>+ struct i40e_pf *pf = vsi->back;
>+ int err = 0;
>+
>+ filter = i40e_find_cloud_filter(vsi, &cls_flower->cookie);
>+
>+ if (!filter)
>+ return -EINVAL;
>+
>+ hash_del(&filter->cloud_node);
>+
>+ if (filter->dst_port)
>+ err = i40e_add_del_cloud_filter_big_buf(vsi, filter, false);
>+ else
>+ err = i40e_add_del_cloud_filter(vsi, filter, false);
>+ if (err) {
>+ kfree(filter);
>+ dev_err(&pf->pdev->dev,
>+ "Failed to delete cloud filter, err %s\n",
>+ i40e_stat_str(&pf->hw, err));
>+ return i40e_aq_rc_to_posix(err, pf->hw.aq.asq_last_status);
>+ }
>+
>+ kfree(filter);
>+ pf->num_cloud_filters--;
>+
>+ if (!pf->num_cloud_filters)
>+ if ((pf->flags & I40E_FLAG_FD_SB_TO_CLOUD_FILTER) &&
>+ !(pf->flags & I40E_FLAG_FD_SB_INACTIVE)) {
>+ pf->flags |= I40E_FLAG_FD_SB_ENABLED;
>+ pf->flags &= ~I40E_FLAG_FD_SB_TO_CLOUD_FILTER;
>+ pf->flags &= ~I40E_FLAG_FD_SB_INACTIVE;
>+ }
>+ return 0;
>+}
>+
>+/**
>+ * i40e_setup_tc_cls_flower - flower classifier offloads
>+ * @netdev: net device to configure
>+ * @type_data: offload data
>+ **/
>+static int i40e_setup_tc_cls_flower(struct net_device *netdev,
>+ struct tc_cls_flower_offload *cls_flower)
>+{
>+ struct i40e_netdev_priv *np = netdev_priv(netdev);
>+ struct i40e_vsi *vsi = np->vsi;
>+
>+ if (!is_classid_clsact_ingress(cls_flower->common.classid) ||
>+ cls_flower->common.chain_index)
>+ return -EOPNOTSUPP;
>+
>+ switch (cls_flower->command) {
>+ case TC_CLSFLOWER_REPLACE:
>+ return i40e_configure_clsflower(vsi, cls_flower);
>+ case TC_CLSFLOWER_DESTROY:
>+ return i40e_delete_clsflower(vsi, cls_flower);
>+ case TC_CLSFLOWER_STATS:
>+ return -EOPNOTSUPP;
>+ default:
>+ return -EINVAL;
>+ }
>+}
>+
> static int __i40e_setup_tc(struct net_device *netdev, enum tc_setup_type type,
> void *type_data)
> {
>- if (type != TC_SETUP_MQPRIO)
>+ switch (type) {
>+ case TC_SETUP_MQPRIO:
>+ return i40e_setup_tc(netdev, type_data);
>+ case TC_SETUP_CLSFLOWER:
>+ return i40e_setup_tc_cls_flower(netdev, type_data);
>+ default:
> return -EOPNOTSUPP;
>-
>- return i40e_setup_tc(netdev, type_data);
>+ }
> }
>
> /**
>@@ -6939,6 +7756,13 @@ static void i40e_cloud_filter_exit(struct i40e_pf *pf)
> kfree(cfilter);
> }
> pf->num_cloud_filters = 0;
>+
>+ if ((pf->flags & I40E_FLAG_FD_SB_TO_CLOUD_FILTER) &&
>+ !(pf->flags & I40E_FLAG_FD_SB_INACTIVE)) {
>+ pf->flags |= I40E_FLAG_FD_SB_ENABLED;
>+ pf->flags &= ~I40E_FLAG_FD_SB_TO_CLOUD_FILTER;
>+ pf->flags &= ~I40E_FLAG_FD_SB_INACTIVE;
>+ }
> }
>
> /**
>@@ -8046,7 +8870,8 @@ static int i40e_reconstitute_veb(struct i40e_veb *veb)
> * i40e_get_capabilities - get info about the HW
> * @pf: the PF struct
> **/
>-static int i40e_get_capabilities(struct i40e_pf *pf)
>+static int i40e_get_capabilities(struct i40e_pf *pf,
>+ enum i40e_admin_queue_opc list_type)
> {
> struct i40e_aqc_list_capabilities_element_resp *cap_buf;
> u16 data_size;
>@@ -8061,9 +8886,8 @@ static int i40e_get_capabilities(struct i40e_pf *pf)
>
> /* this loads the data into the hw struct for us */
> err = i40e_aq_discover_capabilities(&pf->hw, cap_buf, buf_len,
>- &data_size,
>- i40e_aqc_opc_list_func_capabilities,
>- NULL);
>+ &data_size, list_type,
>+ NULL);
> /* data loaded, buffer no longer needed */
> kfree(cap_buf);
>
>@@ -8080,26 +8904,44 @@ static int i40e_get_capabilities(struct i40e_pf *pf)
> }
> } while (err);
>
>- if (pf->hw.debug_mask & I40E_DEBUG_USER)
>- dev_info(&pf->pdev->dev,
>- "pf=%d, num_vfs=%d, msix_pf=%d, msix_vf=%d, fd_g=%d, fd_b=%d, pf_max_q=%d num_vsi=%d\n",
>- pf->hw.pf_id, pf->hw.func_caps.num_vfs,
>- pf->hw.func_caps.num_msix_vectors,
>- pf->hw.func_caps.num_msix_vectors_vf,
>- pf->hw.func_caps.fd_filters_guaranteed,
>- pf->hw.func_caps.fd_filters_best_effort,
>- pf->hw.func_caps.num_tx_qp,
>- pf->hw.func_caps.num_vsis);
>-
>+ if (pf->hw.debug_mask & I40E_DEBUG_USER) {
>+ if (list_type == i40e_aqc_opc_list_func_capabilities) {
>+ dev_info(&pf->pdev->dev,
>+ "pf=%d, num_vfs=%d, msix_pf=%d, msix_vf=%d, fd_g=%d, fd_b=%d, pf_max_q=%d num_vsi=%d\n",
>+ pf->hw.pf_id, pf->hw.func_caps.num_vfs,
>+ pf->hw.func_caps.num_msix_vectors,
>+ pf->hw.func_caps.num_msix_vectors_vf,
>+ pf->hw.func_caps.fd_filters_guaranteed,
>+ pf->hw.func_caps.fd_filters_best_effort,
>+ pf->hw.func_caps.num_tx_qp,
>+ pf->hw.func_caps.num_vsis);
>+ } else if (list_type == i40e_aqc_opc_list_dev_capabilities) {
>+ dev_info(&pf->pdev->dev,
>+ "switch_mode=0x%04x, function_valid=0x%08x\n",
>+ pf->hw.dev_caps.switch_mode,
>+ pf->hw.dev_caps.valid_functions);
>+ dev_info(&pf->pdev->dev,
>+ "SR-IOV=%d, num_vfs for all function=%u\n",
>+ pf->hw.dev_caps.sr_iov_1_1,
>+ pf->hw.dev_caps.num_vfs);
>+ dev_info(&pf->pdev->dev,
>+ "num_vsis=%u, num_rx:%u, num_tx=%u\n",
>+ pf->hw.dev_caps.num_vsis,
>+ pf->hw.dev_caps.num_rx_qp,
>+ pf->hw.dev_caps.num_tx_qp);
>+ }
>+ }
>+ if (list_type == i40e_aqc_opc_list_func_capabilities) {
> #define DEF_NUM_VSI (1 + (pf->hw.func_caps.fcoe ? 1 : 0) \
> + pf->hw.func_caps.num_vfs)
>- if (pf->hw.revision_id == 0 && (DEF_NUM_VSI > pf->hw.func_caps.num_vsis)) {
>- dev_info(&pf->pdev->dev,
>- "got num_vsis %d, setting num_vsis to %d\n",
>- pf->hw.func_caps.num_vsis, DEF_NUM_VSI);
>- pf->hw.func_caps.num_vsis = DEF_NUM_VSI;
>+ if (pf->hw.revision_id == 0 &&
>+ (pf->hw.func_caps.num_vsis < DEF_NUM_VSI)) {
>+ dev_info(&pf->pdev->dev,
>+ "got num_vsis %d, setting num_vsis to %d\n",
>+ pf->hw.func_caps.num_vsis, DEF_NUM_VSI);
>+ pf->hw.func_caps.num_vsis = DEF_NUM_VSI;
>+ }
> }
>-
> return 0;
> }
>
>@@ -8141,6 +8983,7 @@ static void i40e_fdir_sb_setup(struct i40e_pf *pf)
> if (!vsi) {
> dev_info(&pf->pdev->dev, "Couldn't create FDir VSI\n");
> pf->flags &= ~I40E_FLAG_FD_SB_ENABLED;
>+ pf->flags |= I40E_FLAG_FD_SB_INACTIVE;
> return;
> }
> }
>@@ -8163,6 +9006,48 @@ static void i40e_fdir_teardown(struct i40e_pf *pf)
> }
>
> /**
>+ * i40e_rebuild_cloud_filters - Rebuilds cloud filters for VSIs
>+ * @vsi: PF main vsi
>+ * @seid: seid of main or channel VSIs
>+ *
>+ * Rebuilds cloud filters associated with main VSI and channel VSIs if they
>+ * existed before reset
>+ **/
>+static int i40e_rebuild_cloud_filters(struct i40e_vsi *vsi, u16 seid)
>+{
>+ struct i40e_cloud_filter *cfilter;
>+ struct i40e_pf *pf = vsi->back;
>+ struct hlist_node *node;
>+ i40e_status ret;
>+
>+ /* Add cloud filters back if they exist */
>+ if (hlist_empty(&pf->cloud_filter_list))
>+ return 0;
>+
>+ hlist_for_each_entry_safe(cfilter, node, &pf->cloud_filter_list,
>+ cloud_node) {
>+ if (cfilter->seid != seid)
>+ continue;
>+
>+ if (cfilter->dst_port)
>+ ret = i40e_add_del_cloud_filter_big_buf(vsi, cfilter,
>+ true);
>+ else
>+ ret = i40e_add_del_cloud_filter(vsi, cfilter, true);
>+
>+ if (ret) {
>+ dev_dbg(&pf->pdev->dev,
>+ "Failed to rebuild cloud filter, err %s aq_err %s\n",
>+ i40e_stat_str(&pf->hw, ret),
>+ i40e_aq_str(&pf->hw,
>+ pf->hw.aq.asq_last_status));
>+ return ret;
>+ }
>+ }
>+ return 0;
>+}
>+
>+/**
> * i40e_rebuild_channels - Rebuilds channel VSIs if they existed before reset
> * @vsi: PF main vsi
> *
>@@ -8199,6 +9084,13 @@ static int i40e_rebuild_channels(struct i40e_vsi *vsi)
> I40E_BW_CREDIT_DIVISOR,
> ch->seid);
> }
>+ ret = i40e_rebuild_cloud_filters(vsi, ch->seid);
>+ if (ret) {
>+ dev_dbg(&vsi->back->pdev->dev,
>+ "Failed to rebuild cloud filters for channel VSI %u\n",
>+ ch->seid);
>+ return ret;
>+ }
> }
> return 0;
> }
>@@ -8365,7 +9257,7 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
> i40e_verify_eeprom(pf);
>
> i40e_clear_pxe_mode(hw);
>- ret = i40e_get_capabilities(pf);
>+ ret = i40e_get_capabilities(pf, i40e_aqc_opc_list_func_capabilities);
> if (ret)
> goto end_core_reset;
>
>@@ -8482,6 +9374,10 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
> goto end_unlock;
> }
>
>+ ret = i40e_rebuild_cloud_filters(vsi, vsi->seid);
>+ if (ret)
>+ goto end_unlock;
>+
> /* PF Main VSI is rebuild by now, go ahead and rebuild channel VSIs
> * for this main VSI if they exist
> */
>@@ -9404,6 +10300,7 @@ static int i40e_init_msix(struct i40e_pf *pf)
> (pf->num_fdsb_msix == 0)) {
> dev_info(&pf->pdev->dev, "Sideband Flowdir disabled, not enough MSI-X vectors\n");
> pf->flags &= ~I40E_FLAG_FD_SB_ENABLED;
>+ pf->flags |= I40E_FLAG_FD_SB_INACTIVE;
> }
> if ((pf->flags & I40E_FLAG_VMDQ_ENABLED) &&
> (pf->num_vmdq_msix == 0)) {
>@@ -9521,6 +10418,7 @@ static int i40e_init_interrupt_scheme(struct i40e_pf *pf)
> I40E_FLAG_FD_SB_ENABLED |
> I40E_FLAG_FD_ATR_ENABLED |
> I40E_FLAG_VMDQ_ENABLED);
>+ pf->flags |= I40E_FLAG_FD_SB_INACTIVE;
>
> /* rework the queue expectations without MSIX */
> i40e_determine_queue_usage(pf);
>@@ -10263,9 +11161,13 @@ bool i40e_set_ntuple(struct i40e_pf *pf, netdev_features_t features)
> /* Enable filters and mark for reset */
> if (!(pf->flags & I40E_FLAG_FD_SB_ENABLED))
> need_reset = true;
>- /* enable FD_SB only if there is MSI-X vector */
>- if (pf->num_fdsb_msix > 0)
>+ /* enable FD_SB only if there is MSI-X vector and no cloud
>+ * filters exist
>+ */
>+ if (pf->num_fdsb_msix > 0 && !pf->num_cloud_filters) {
> pf->flags |= I40E_FLAG_FD_SB_ENABLED;
>+ pf->flags &= ~I40E_FLAG_FD_SB_INACTIVE;
>+ }
> } else {
> /* turn off filters, mark for reset and clear SW filter list */
> if (pf->flags & I40E_FLAG_FD_SB_ENABLED) {
>@@ -10274,6 +11176,8 @@ bool i40e_set_ntuple(struct i40e_pf *pf, netdev_features_t features)
> }
> pf->flags &= ~(I40E_FLAG_FD_SB_ENABLED |
> I40E_FLAG_FD_SB_AUTO_DISABLED);
>+ pf->flags |= I40E_FLAG_FD_SB_INACTIVE;
>+
> /* reset fd counters */
> pf->fd_add_err = 0;
> pf->fd_atr_cnt = 0;
>@@ -10857,7 +11761,8 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
> netdev->hw_features |= NETIF_F_NTUPLE;
> hw_features = hw_enc_features |
> NETIF_F_HW_VLAN_CTAG_TX |
>- NETIF_F_HW_VLAN_CTAG_RX;
>+ NETIF_F_HW_VLAN_CTAG_RX |
>+ NETIF_F_HW_TC;
>
> netdev->hw_features |= hw_features;
>
>@@ -12159,8 +13064,10 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit)
> */
>
> if ((pf->hw.pf_id == 0) &&
>- !(pf->flags & I40E_FLAG_TRUE_PROMISC_SUPPORT))
>+ !(pf->flags & I40E_FLAG_TRUE_PROMISC_SUPPORT)) {
> flags = I40E_AQ_SET_SWITCH_CFG_PROMISC;
>+ pf->last_sw_conf_flags = flags;
>+ }
>
> if (pf->hw.pf_id == 0) {
> u16 valid_flags;
>@@ -12176,6 +13083,7 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit)
> pf->hw.aq.asq_last_status));
> /* not a fatal problem, just keep going */
> }
>+ pf->last_sw_conf_valid_flags = valid_flags;
> }
>
> /* first time setup */
>@@ -12273,6 +13181,7 @@ static void i40e_determine_queue_usage(struct i40e_pf *pf)
> I40E_FLAG_DCB_ENABLED |
> I40E_FLAG_SRIOV_ENABLED |
> I40E_FLAG_VMDQ_ENABLED);
>+ pf->flags |= I40E_FLAG_FD_SB_INACTIVE;
> } else if (!(pf->flags & (I40E_FLAG_RSS_ENABLED |
> I40E_FLAG_FD_SB_ENABLED |
> I40E_FLAG_FD_ATR_ENABLED |
>@@ -12287,6 +13196,7 @@ static void i40e_determine_queue_usage(struct i40e_pf *pf)
> I40E_FLAG_FD_ATR_ENABLED |
> I40E_FLAG_DCB_ENABLED |
> I40E_FLAG_VMDQ_ENABLED);
>+ pf->flags |= I40E_FLAG_FD_SB_INACTIVE;
> } else {
> /* Not enough queues for all TCs */
> if ((pf->flags & I40E_FLAG_DCB_CAPABLE) &&
>@@ -12310,6 +13220,7 @@ static void i40e_determine_queue_usage(struct i40e_pf *pf)
> queues_left -= 1; /* save 1 queue for FD */
> } else {
> pf->flags &= ~I40E_FLAG_FD_SB_ENABLED;
>+ pf->flags |= I40E_FLAG_FD_SB_INACTIVE;
> dev_info(&pf->pdev->dev, "not enough queues for Flow Director. Flow Director feature is disabled\n");
> }
> }
>@@ -12613,7 +13524,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> dev_warn(&pdev->dev, "This device is a pre-production adapter/LOM. Please be aware there may be issues with your hardware. If you are experiencing problems please contact your Intel or hardware representative who provided you with this hardware.\n");
>
> i40e_clear_pxe_mode(hw);
>- err = i40e_get_capabilities(pf);
>+ err = i40e_get_capabilities(pf, i40e_aqc_opc_list_func_capabilities);
> if (err)
> goto err_adminq_setup;
>
>diff --git a/drivers/net/ethernet/intel/i40e/i40e_prototype.h b/drivers/net/ethernet/intel/i40e/i40e_prototype.h
>index 92869f5..3bb6659 100644
>--- a/drivers/net/ethernet/intel/i40e/i40e_prototype.h
>+++ b/drivers/net/ethernet/intel/i40e/i40e_prototype.h
>@@ -283,6 +283,22 @@ i40e_status i40e_aq_query_switch_comp_bw_config(struct i40e_hw *hw,
> struct i40e_asq_cmd_details *cmd_details);
> i40e_status i40e_aq_resume_port_tx(struct i40e_hw *hw,
> struct i40e_asq_cmd_details *cmd_details);
>+i40e_status
>+i40e_aq_add_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
>+ struct i40e_aqc_cloud_filters_element_bb *filters,
>+ u8 filter_count);
>+enum i40e_status_code
>+i40e_aq_add_cloud_filters(struct i40e_hw *hw, u16 vsi,
>+ struct i40e_aqc_cloud_filters_element_data *filters,
>+ u8 filter_count);
>+enum i40e_status_code
>+i40e_aq_rem_cloud_filters(struct i40e_hw *hw, u16 vsi,
>+ struct i40e_aqc_cloud_filters_element_data *filters,
>+ u8 filter_count);
>+i40e_status
>+i40e_aq_rem_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
>+ struct i40e_aqc_cloud_filters_element_bb *filters,
>+ u8 filter_count);
> i40e_status i40e_read_lldp_cfg(struct i40e_hw *hw,
> struct i40e_lldp_variables *lldp_cfg);
> /* i40e_common */
>diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h
>index c019f46..af38881 100644
>--- a/drivers/net/ethernet/intel/i40e/i40e_type.h
>+++ b/drivers/net/ethernet/intel/i40e/i40e_type.h
>@@ -287,6 +287,7 @@ struct i40e_hw_capabilities {
> #define I40E_NVM_IMAGE_TYPE_MODE1 0x6
> #define I40E_NVM_IMAGE_TYPE_MODE2 0x7
> #define I40E_NVM_IMAGE_TYPE_MODE3 0x8
>+#define I40E_SWITCH_MODE_MASK 0xF
>
> u32 management_mode;
> u32 mng_protocols_over_mctp;
>diff --git a/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h b/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h
>index b8c78bf..4fe27f0 100644
>--- a/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h
>+++ b/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h
>@@ -1360,6 +1360,9 @@ struct i40e_aqc_cloud_filters_element_data {
> struct {
> u8 data[16];
> } v6;
>+ struct {
>+ __le16 data[8];
>+ } raw_v6;
> } ipaddr;
> __le16 flags;
> #define I40E_AQC_ADD_CLOUD_FILTER_SHIFT 0
>
^ permalink raw reply
* netfilter: xt_bpf: ABI issue in xt_bpf_info_v1?
From: Shmulik Ladkani @ 2017-09-13 13:24 UTC (permalink / raw)
To: netfilter-devel, Pablo Neira Ayuso
Cc: netdev, Willem de Bruijn, Rafael Buchbinder, shmulik.ladkani,
eyal
Hi,
Commit 2c16d60 'netfilter: xt_bpf: support ebpf' introduced
'xt_bpf_info_v1', to support attaching an eBPF object by fd.
Alas, seems this ABI is problematic, as the 'fd', which is local to the
process attaching the ebpf object (namely iptables) is stored in the
matchinfo structure.
This leads to subsequent invocation of iptables to fail:
# iptables -A INPUT -m bpf --object-pinned /sys/fs/bpf/xxx -j ACCEPT
# iptables -A INPUT -s 5.6.7.8 -j ACCEPT
iptables: Invalid argument. Run `dmesg' for more information.
Tracing 2nd invocation shows:
setsockopt(4, SOL_IP, IPT_SO_SET_REPLACE, "filter\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 5400) = -1 EINVAL
In the 2nd invocation, iptables loads existing rules from the kernel
using IPT_SO_GET_ENTRIES, adds the new innocent one, and then issues
IPT_SO_SET_REPLACE.
However the existing rules contain the former ebpf rule which contains
the fd number from the initial 'iptables -m bpf' invocation.
Thus, when IPT_SO_SET_REPLACE eventually hits 'bpf_mt_check_v1', and
'bpf_prog_get_type' is called, the arbitrary fd has either no associated
file, or has no associated bpf_prog - leading 'bpf_prog_get_type' to
fail.
One way to fix is to have iptables open the object (using the stored
xt_bpf_info_v1->path), gaining a new process local fd for the object,
just after getting the rules from IPT_SO_GET_ENTRIES.
However we didn't see any other extensions doing something like that in
iptables.
Another way to solve is to fix the ABI (or have a v2 one), that does NOT
pass the fd from userspace, only the path of the pinned object.
Then, 'bpf_mt_check_v1' will open the file from the given path in order
to get the bpf_prog.
Please advise.
Best,
Shmulik
^ permalink raw reply
* Re: [RFC PATCH v3 2/7] sched: act_mirred: Traffic class option for mirror/redirect action
From: Jiri Pirko @ 2017-09-13 13:18 UTC (permalink / raw)
To: Amritha Nambiar
Cc: intel-wired-lan, jeffrey.t.kirsher, alexander.h.duyck, netdev,
mlxsw
In-Reply-To: <150529676456.57063.7605464456122745976.stgit@anamdev.jf.intel.com>
Wed, Sep 13, 2017 at 11:59:24AM CEST, amritha.nambiar@intel.com wrote:
>Adds optional traffic class parameter to the mirror/redirect action.
>The mirror/redirect action is extended to forward to a traffic
>class on the device if the traffic class index is provided in
>addition to the device's ifindex.
Do I understand it correctly that you just abuse mirred to pas tcclass
index down to the driver, without actually doing anything with the value
inside mirred-code ? That is a bit confusing for me.
^ permalink raw reply
* Re: [PATCH 05/10] drivers:net: return -ENOMEM on allocation failure.
From: Allen @ 2017-09-13 13:05 UTC (permalink / raw)
To: Andrew Lunn
Cc: linux-kernel, nouveau, linux-crypto, dri-devel,
MPT-FusionLinux.pdl, linux-scsi, netdev, megaraidlinux.pdl,
target-devel, linux-fbdev, linux-btrfs
In-Reply-To: <20170913120909.GA11820@lunn.ch>
> propagates the -1. That is only called by bond_open() with:
>
> if (bond_alb_initialize(bond, (BOND_MODE(bond) == BOND_MODE_ALB)))
> return -ENOMEM;
>
> So you might want to also modify this code, to return the return
> value, rather than use the hard coded ENOMEM.
>
I'll modify the above and send it out a separate patch.
Thank you.
^ permalink raw reply
* Re: [PATCH 06/10] drivers:ethernet: return -ENOMEM on allocation failure.
From: Allen @ 2017-09-13 13:04 UTC (permalink / raw)
To: Andrew Lunn
Cc: linux-kernel, nouveau, linux-crypto, dri-devel,
MPT-FusionLinux.pdl, linux-scsi, netdev, megaraidlinux.pdl,
target-devel, linux-fbdev, linux-btrfs
In-Reply-To: <20170913121628.GB11820@lunn.ch>
>
> static int cas_alloc_rxds(struct cas *cp)
> {
> int i;
>
> for (i = 0; i < N_RX_DESC_RINGS; i++) {
> if (cas_alloc_rx_desc(cp, i) < 0) {
> cas_free_rxds(cp);
> return -1;
> }
> }
> return 0;
> }
>
> Again, your change is correct, but in the end the value is not used.
> And if you fix it at the cas_alloc_rxds level, you also need a fix at
> the next level up:
>
> err = -ENOMEM;
> if (cas_tx_tiny_alloc(cp) < 0)
> goto err_unlock;
>
> /* alloc rx descriptors */
> if (cas_alloc_rxds(cp) < 0)
> goto err_tx_tiny;
>
> again, the return value is discarded.
I agree. I could send out v2 with fixes at both level.
- Allen
^ permalink raw reply
* Re: [PATCH v2] ipv4: Namespaceify tcp_fastopen knob
From: Eric Dumazet @ 2017-09-13 13:02 UTC (permalink / raw)
To: Haishuang Yan
Cc: David S. Miller, Alexey Kuznetsov, Eric Dumazet, Luca BRUNO,
netdev, linux-kernel
In-Reply-To: <1505306674.15310.155.camel@edumazet-glaptop3.roam.corp.google.com>
On Wed, 2017-09-13 at 05:44 -0700, Eric Dumazet wrote:
> On Wed, 2017-09-13 at 19:19 +0800, Haishuang Yan wrote:
> > Different namespace application might require enable TCP Fast Open
> > feature independently of the host.
> >
>
> Poor changelog, no actual description / list of sysctls that are moved
> to per netns.
>
> And looking at the patch, it seems your conversion is not complete.
>
> So I will ask you to provide more evidence that you tested your patch
> next time you submit it.
I suggest you move one sysctl at a time, in a patch series.
It will be easier to document and test for you, and review for us.
Thanks.
^ permalink raw reply
* Re: [LPC] 2nd RDMA Mini-Summit Schedule
From: Leon Romanovsky @ 2017-09-13 13:02 UTC (permalink / raw)
To: RDMA mailing list
Cc: linux-netdev, NVME mailing list, Jason Gunthorpe, Bart Van Assche,
Knut Omang, Christoph Lameter, Don Dutile, Liran Liss, Tzahi Oved,
Matan Barak, Dennis Dalessandro, Yuval Shaia, Marcel Apfelbaum,
lwn
In-Reply-To: <20170907051805.GA19175@mtr-leonro.local>
[-- Attachment #1: Type: text/plain, Size: 3025 bytes --]
On Thu, Sep 07, 2017 at 08:18:05AM +0300, Leon Romanovsky wrote:
> Hi,
>
> We're happy to announce schedule of the 2nd RDMA mini-summit, which will be
> held as part of coming Linux Plumbers Conference 2017.
>
> During the conference, we will have two sessions: main track session and
> round table session.
>
> First session will be held on Thursday, September 14, 2017 from 9:30am – 12:30pm
> with the topics relevant for the wider audience.
>
> In the second session, we will focus on more face to face discussions in round
> table format and it will be scheduled a little bit later once we will get meeting
> room.
UPDATE:
The round table will take place at 2:00pm on Thursday, September 14,
2017 in one of the speakers's suites (3rd floor, near Georgia I/II).
Thanks
>
> ---------------------------------------------------------------------------------------
> FIRST SESSION:
> ---------------------------------------------------------------------------------------
> * Backporting issues with multi-subsystem device (RDMA + netdev + more) by Don Dutile
> - More and more devices in RDMA are dependent on netdev as well as other
> subsystems -- target, NFS, scsi, block, cgroups, SELinux.... Can we make
> backporting task for distro people easier?
> * kABI Update by Matan Barak
> - Going forward with a flexible and secure RDMA kABI
> * System Boot and RDMA by Jason Gunthrope
> - Discuss boot-time issues with the RDMA subsystem
> * Paravirtual RDMA device by Marcel Apfelbaum and Yuval Shaia
> - QEMU's limited RDMA support leaves it behind other modern hypervisors.
> Marcel and Yuval will present the implementation of an emulated RDMA device,
> analyze its performance and usability, and finally talk about future plans
> for a possible virtio-rdma device.
> * TX Flow Steering for IPsec by Liran Liss (pending time slot)
> - The IPsec protocol provides both encryption and authentication for IP
> protocol packets. Users of the raw ethernet QP that send/receive IPsec packets
> could benefit from the IPsec crypto offloads capabilities that are
> available in recent NICs.
> * OpenFabrics Alliance - Status and New Directions by Jason Gunthrope
> * BOF - Open Discussion
> - Open discussion with the community lead by Leon Romanovsky, Jason Gunthorpe,
> Christoph Lameter and Dennis Dalessandro
>
> ---------------------------------------------------------------------------------------
> ROUND TABLE SESSION:
> ---------------------------------------------------------------------------------------
> Possible list, bring your own topics:
> * RDMA and ULPs
> * Verbs testing suite
> * RDMA netlink and RDMAtool future plans
> * RDMA and the Linux IP stack
> * Infrastructure issues with Travis CI
> * Infrastructure gaps with rdma-core
> * Packaging as part of CI for rdma-core.
> * ....
>
> See you next week at Linux Plumber Conference 2017.
>
> Thanks
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ 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