* Re: [PATCH, net-next 1/2] bpf: btf: avoid -Wreturn-type warning
From: Song Liu @ 2018-05-25 21:53 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Alexei Starovoitov, Daniel Borkmann, Martin Lau,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <20180525213331.2115471-1-arnd@arndb.de>
> On May 25, 2018, at 2:33 PM, Arnd Bergmann <arnd@arndb.de> wrote:
>
> gcc warns about a noreturn function possibly returning in
> some configurations:
>
> kernel/bpf/btf.c: In function 'env_type_is_resolve_sink':
> kernel/bpf/btf.c:729:1: error: control reaches end of non-void function [-Werror=return-type]
>
> Using BUG() instead of BUG_ON() avoids that warning and otherwise
> does the exact same thing.
>
> Fixes: eb3f595dab40 ("bpf: btf: Validate type reference")
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> kernel/bpf/btf.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
> index 9cbeabb5aca3..2822a0cf4f48 100644
> --- a/kernel/bpf/btf.c
> +++ b/kernel/bpf/btf.c
> @@ -749,7 +749,7 @@ static bool env_type_is_resolve_sink(const struct btf_verifier_env *env,
> !btf_type_is_array(next_type) &&
> !btf_type_is_struct(next_type);
> default:
> - BUG_ON(1);
> + BUG();
> }
> }
>
> --
> 2.9.0
>
Acked-by: Song Liu <songliubraving@fb.com>
^ permalink raw reply
* Re: [PATCH, net-next 2/2] bpf: avoid -Wmaybe-uninitialized warning
From: Song Liu @ 2018-05-25 21:54 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Alexei Starovoitov, Daniel Borkmann, Yonghong Song,
David S. Miller, Martin Lau, Chenbo Feng, Jakub Kicinski,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <20180525213331.2115471-2-arnd@arndb.de>
> On May 25, 2018, at 2:33 PM, Arnd Bergmann <arnd@arndb.de> wrote:
>
> The stack_map_get_build_id_offset() function is too long for gcc to track
> whether 'work' may or may not be initialized at the end of it, leading
> to a false-positive warning:
>
> kernel/bpf/stackmap.c: In function 'stack_map_get_build_id_offset':
> kernel/bpf/stackmap.c:334:13: error: 'work' may be used uninitialized in this function [-Werror=maybe-uninitialized]
>
> This removes the 'in_nmi_ctx' flag and uses the state of that variable
> itself to see if it got initialized.
>
> Fixes: bae77c5eb5b2 ("bpf: enable stackmap with build_id in nmi context")
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> kernel/bpf/stackmap.c | 7 +++----
> 1 file changed, 3 insertions(+), 4 deletions(-)
>
> diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c
> index b59ace0f0f09..b675a3f3d141 100644
> --- a/kernel/bpf/stackmap.c
> +++ b/kernel/bpf/stackmap.c
> @@ -285,11 +285,10 @@ static void stack_map_get_build_id_offset(struct bpf_stack_build_id *id_offs,
> {
> int i;
> struct vm_area_struct *vma;
> - bool in_nmi_ctx = in_nmi();
> bool irq_work_busy = false;
> - struct stack_map_irq_work *work;
> + struct stack_map_irq_work *work = NULL;
>
> - if (in_nmi_ctx) {
> + if (in_nmi()) {
> work = this_cpu_ptr(&up_read_work);
> if (work->irq_work.flags & IRQ_WORK_BUSY)
> /* cannot queue more up_read, fallback */
> @@ -328,7 +327,7 @@ static void stack_map_get_build_id_offset(struct bpf_stack_build_id *id_offs,
> id_offs[i].status = BPF_STACK_BUILD_ID_VALID;
> }
>
> - if (!in_nmi_ctx) {
> + if (!work) {
> up_read(¤t->mm->mmap_sem);
> } else {
> work->sem = ¤t->mm->mmap_sem;
> --
> 2.9.0
>
Acked-by: Song Liu <songliubraving@fb.com>
^ permalink raw reply
* Re: [PATCH bpf-next] libbpf: Install btf.h with libbpf
From: Song Liu @ 2018-05-25 21:57 UTC (permalink / raw)
To: Martin KaFai Lau; +Cc: Andrey Ignatov, netdev, ast, daniel, kernel-team
In-Reply-To: <20180525173341.yqpy3nhe4whtfm62@kafai-mbp>
On Fri, May 25, 2018 at 10:33 AM, Martin KaFai Lau <kafai@fb.com> wrote:
> On Fri, May 25, 2018 at 10:23:13AM -0700, Andrey Ignatov wrote:
>> install_headers target should contain all headers that are part of
>> libbpf. Add missing btf.h
>>
>> Signed-off-by: Andrey Ignatov <rdna@fb.com>
> Acked-by: Martin KaFai Lau <kafai@fb.com>
Acked-by: Song Liu <songliubraving@fb.com>
^ permalink raw reply
* Re: [PATCH v2 net-next] tcp: use data length instead of skb->len in tcp_probe
From: Song Liu @ 2018-05-25 21:59 UTC (permalink / raw)
To: Yafang Shao
Cc: davem@davemloft.net, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <1527243245-29582-1-git-send-email-laoar.shao@gmail.com>
> On May 25, 2018, at 3:14 AM, Yafang Shao <laoar.shao@gmail.com> wrote:
>
> skb->len is meaningless to user.
> data length could be more helpful, with which we can easily filter out
> the packet without payload.
>
> Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
Acked-by: Song Liu <songliubraving@fb.com>
> ---
> include/trace/events/tcp.h | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/include/trace/events/tcp.h b/include/trace/events/tcp.h
> index c1a5284..703abb6 100644
> --- a/include/trace/events/tcp.h
> +++ b/include/trace/events/tcp.h
> @@ -236,7 +236,7 @@
> __field(__u16, sport)
> __field(__u16, dport)
> __field(__u32, mark)
> - __field(__u16, length)
> + __field(__u16, data_len)
> __field(__u32, snd_nxt)
> __field(__u32, snd_una)
> __field(__u32, snd_cwnd)
> @@ -261,7 +261,7 @@
> __entry->dport = ntohs(inet->inet_dport);
> __entry->mark = skb->mark;
>
> - __entry->length = skb->len;
> + __entry->data_len = skb->len - tcp_hdrlen(skb);
> __entry->snd_nxt = tp->snd_nxt;
> __entry->snd_una = tp->snd_una;
> __entry->snd_cwnd = tp->snd_cwnd;
> @@ -272,9 +272,9 @@
> __entry->sock_cookie = sock_gen_cookie(sk);
> ),
>
> - TP_printk("src=%pISpc dest=%pISpc mark=%#x length=%d snd_nxt=%#x snd_una=%#x snd_cwnd=%u ssthresh=%u snd_wnd=%u srtt=%u rcv_wnd=%u sock_cookie=%llx",
> + TP_printk("src=%pISpc dest=%pISpc mark=%#x data_len=%d snd_nxt=%#x snd_una=%#x snd_cwnd=%u ssthresh=%u snd_wnd=%u srtt=%u rcv_wnd=%u sock_cookie=%llx",
> __entry->saddr, __entry->daddr, __entry->mark,
> - __entry->length, __entry->snd_nxt, __entry->snd_una,
> + __entry->data_len, __entry->snd_nxt, __entry->snd_una,
> __entry->snd_cwnd, __entry->ssthresh, __entry->snd_wnd,
> __entry->srtt, __entry->rcv_wnd, __entry->sock_cookie)
> );
> --
> 1.8.3.1
>
^ permalink raw reply
* Re: [PATCH net-next v12 2/5] netvsc: refactor notifier/event handling code to use the failover framework
From: Stephen Hemminger @ 2018-05-25 22:34 UTC (permalink / raw)
To: Sridhar Samudrala
Cc: alexander.h.duyck, virtio-dev, jiri, mst, kubakici, netdev,
virtualization, loseweigh, anjali.singhai, aaron.f.brown, davem
In-Reply-To: <1527180917-39737-3-git-send-email-sridhar.samudrala@intel.com>
On Thu, 24 May 2018 09:55:14 -0700
Sridhar Samudrala <sridhar.samudrala@intel.com> wrote:
> --- a/drivers/net/hyperv/Kconfig
> +++ b/drivers/net/hyperv/Kconfig
> @@ -2,5 +2,6 @@ config HYPERV_NET
> tristate "Microsoft Hyper-V virtual network driver"
> depends on HYPERV
> select UCS2_STRING
> + select FAILOVER
When I take a working kernel config, add the patches then do
make oldconfig
It is not autoselecting FAILOVER, it prompts me for it. This means
if user says no then a non-working netvsc device is made.
^ permalink raw reply
* Re: [PATCH net-next v12 1/5] net: Introduce generic failover module
From: Stephen Hemminger @ 2018-05-25 22:37 UTC (permalink / raw)
To: Sridhar Samudrala
Cc: mst, davem, netdev, virtualization, virtio-dev, jesse.brandeburg,
alexander.h.duyck, kubakici, jasowang, loseweigh, jiri,
aaron.f.brown, anjali.singhai
In-Reply-To: <1527180917-39737-2-git-send-email-sridhar.samudrala@intel.com>
On Thu, 24 May 2018 09:55:13 -0700
Sridhar Samudrala <sridhar.samudrala@intel.com> wrote:
> + spin_lock(&failover_lock);
Since register is not in fast path, this should be a mutex?
> +int failover_slave_unregister(struct net_device *slave_dev)
> +{
> + struct net_device *failover_dev;
> + struct failover_ops *fops;
> +
> + if (!netif_is_failover_slave(slave_dev))
> + goto done;
> +
> + ASSERT_RTNL();
> +
> + failover_dev = failover_get_bymac(slave_dev->perm_addr, &fops);
> + if (!failover_dev)
> + goto done;
Since the slave device must have a master device set already, why not use
that instead of searching by MAC address on unregister or link change.
^ permalink raw reply
* Re: [PATCH net-next v12 1/5] net: Introduce generic failover module
From: Stephen Hemminger @ 2018-05-25 22:38 UTC (permalink / raw)
To: Sridhar Samudrala
Cc: mst, davem, netdev, virtualization, virtio-dev, jesse.brandeburg,
alexander.h.duyck, kubakici, jasowang, loseweigh, jiri,
aaron.f.brown, anjali.singhai
In-Reply-To: <1527180917-39737-2-git-send-email-sridhar.samudrala@intel.com>
On Thu, 24 May 2018 09:55:13 -0700
Sridhar Samudrala <sridhar.samudrala@intel.com> wrote:
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 03ed492c4e14..0f4ba52b641d 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -1421,6 +1421,8 @@ struct net_device_ops {
> * entity (i.e. the master device for bridged veth)
> * @IFF_MACSEC: device is a MACsec device
> * @IFF_NO_RX_HANDLER: device doesn't support the rx_handler hook
> + * @IFF_FAILOVER: device is a failover master device
> + * @IFF_FAILOVER_SLAVE: device is lower dev of a failover master device
> */
> enum netdev_priv_flags {
> IFF_802_1Q_VLAN = 1<<0,
> @@ -1450,6 +1452,8 @@ enum netdev_priv_flags {
> IFF_PHONY_HEADROOM = 1<<24,
> IFF_MACSEC = 1<<25,
> IFF_NO_RX_HANDLER = 1<<26,
> + IFF_FAILOVER = 1<<27,
> + IFF_FAILOVER_SLAVE = 1<<28,
> };
Why is FAILOVER any different than other master/slave relationships.
I don't think you need to take up precious netdev flag bits for this.
^ permalink raw reply
* Re: [PATCH net-next v12 1/5] net: Introduce generic failover module
From: Samudrala, Sridhar @ 2018-05-25 23:04 UTC (permalink / raw)
To: Stephen Hemminger
Cc: alexander.h.duyck, virtio-dev, jiri, mst, kubakici, netdev,
virtualization, loseweigh, anjali.singhai, aaron.f.brown, davem
In-Reply-To: <20180525153744.2b53c449@xeon-e3>
[-- Attachment #1.1: Type: text/plain, Size: 967 bytes --]
On 5/25/2018 3:37 PM, Stephen Hemminger wrote:
> On Thu, 24 May 2018 09:55:13 -0700
> Sridhar Samudrala <sridhar.samudrala@intel.com> wrote:
>
>
>> + spin_lock(&failover_lock);
> Since register is not in fast path, this should be a mutex?
This is Jiri's comment which made me to switch to spinlock from mutex
>> Why mutex? Apparently you don't need to sleep while holding a lock.
>> Simple spinlock would do.
>
>
>> +int failover_slave_unregister(struct net_device *slave_dev)
>> +{
>> + struct net_device *failover_dev;
>> + struct failover_ops *fops;
>> +
>> + if (!netif_is_failover_slave(slave_dev))
>> + goto done;
>> +
>> + ASSERT_RTNL();
>> +
>> + failover_dev = failover_get_bymac(slave_dev->perm_addr, &fops);
>> + if (!failover_dev)
>> + goto done;
> Since the slave device must have a master device set already, why not use
> that instead of searching by MAC address on unregister or link change.
>
We also need to get the fops(failover_ops)
[-- Attachment #1.2: Type: text/html, Size: 36732 bytes --]
[-- Attachment #2: Type: text/plain, Size: 183 bytes --]
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply
* Re: [PATCH net-next v12 1/5] net: Introduce generic failover module
From: Samudrala, Sridhar @ 2018-05-25 23:06 UTC (permalink / raw)
To: Stephen Hemminger
Cc: mst, davem, netdev, virtualization, virtio-dev, jesse.brandeburg,
alexander.h.duyck, kubakici, jasowang, loseweigh, jiri,
aaron.f.brown, anjali.singhai
In-Reply-To: <20180525153843.503ee052@xeon-e3>
On 5/25/2018 3:38 PM, Stephen Hemminger wrote:
> On Thu, 24 May 2018 09:55:13 -0700
> Sridhar Samudrala <sridhar.samudrala@intel.com> wrote:
>
>> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
>> index 03ed492c4e14..0f4ba52b641d 100644
>> --- a/include/linux/netdevice.h
>> +++ b/include/linux/netdevice.h
>> @@ -1421,6 +1421,8 @@ struct net_device_ops {
>> * entity (i.e. the master device for bridged veth)
>> * @IFF_MACSEC: device is a MACsec device
>> * @IFF_NO_RX_HANDLER: device doesn't support the rx_handler hook
>> + * @IFF_FAILOVER: device is a failover master device
>> + * @IFF_FAILOVER_SLAVE: device is lower dev of a failover master device
>> */
>> enum netdev_priv_flags {
>> IFF_802_1Q_VLAN = 1<<0,
>> @@ -1450,6 +1452,8 @@ enum netdev_priv_flags {
>> IFF_PHONY_HEADROOM = 1<<24,
>> IFF_MACSEC = 1<<25,
>> IFF_NO_RX_HANDLER = 1<<26,
>> + IFF_FAILOVER = 1<<27,
>> + IFF_FAILOVER_SLAVE = 1<<28,
>> };
> Why is FAILOVER any different than other master/slave relationships.
> I don't think you need to take up precious netdev flag bits for this.
These are netdev priv flags.
Jiri says that IFF_MASTER/IFF_SLAVE are bonding specific flags and cannot be used
with other failover mechanisms. Team also doesn't use this flags and it has its own
priv_flags.
^ permalink raw reply
* Re: [PATCH net-next v12 2/5] netvsc: refactor notifier/event handling code to use the failover framework
From: Samudrala, Sridhar @ 2018-05-25 23:11 UTC (permalink / raw)
To: Stephen Hemminger
Cc: alexander.h.duyck, virtio-dev, jiri, mst, kubakici, netdev,
virtualization, loseweigh, anjali.singhai, aaron.f.brown, davem
In-Reply-To: <20180525153456.28b44c7c@xeon-e3>
On 5/25/2018 3:34 PM, Stephen Hemminger wrote:
> On Thu, 24 May 2018 09:55:14 -0700
> Sridhar Samudrala <sridhar.samudrala@intel.com> wrote:
>
>> --- a/drivers/net/hyperv/Kconfig
>> +++ b/drivers/net/hyperv/Kconfig
>> @@ -2,5 +2,6 @@ config HYPERV_NET
>> tristate "Microsoft Hyper-V virtual network driver"
>> depends on HYPERV
>> select UCS2_STRING
>> + select FAILOVER
> When I take a working kernel config, add the patches then do
> make oldconfig
>
> It is not autoselecting FAILOVER, it prompts me for it. This means
> if user says no then a non-working netvsc device is made.
I see
Generic failover module (FAILOVER) [M/y/?] (NEW)
So the user is given an option to either build as a Module or part of the
kernel. 'n' is not an option.
^ permalink raw reply
* Re: mmotm 2018-05-25-14-52 uploaded (drivers/net/ethernet/ti/davinci_mdio.c)
From: Randy Dunlap @ 2018-05-25 23:15 UTC (permalink / raw)
To: akpm, broonie, mhocko, sfr, linux-next, linux-kernel, mm-commits
Cc: Anant Gole, Chaithrika U S, netdev@vger.kernel.org
In-Reply-To: <26483e60-ab26-494c-b923-86c267cfdac0@infradead.org>
[forgot to add netdev]
On 05/25/2018 04:14 PM, Randy Dunlap wrote:
> On 05/25/2018 02:52 PM, akpm@linux-foundation.org wrote:
>> The mm-of-the-moment snapshot 2018-05-25-14-52 has been uploaded to
>>
>> http://www.ozlabs.org/~akpm/mmotm/
>>
>> mmotm-readme.txt says
>>
>> README for mm-of-the-moment:
>>
>> http://www.ozlabs.org/~akpm/mmotm/
>>
>> This is a snapshot of my -mm patch queue. Uploaded at random hopefully
>> more than once a week.
>
> on x86_64:
> # CONFIG_OF is not set
>
> CC drivers/net/ethernet/ti/davinci_cpdma.o
> ../drivers/net/ethernet/ti/davinci_mdio.c: In function 'davinci_mdio_probe':
> ../drivers/net/ethernet/ti/davinci_mdio.c:380:3: error: implicit declaration of function 'davinci_mdio_probe_dt' [-Werror=implicit-function-declaration]
> ret = davinci_mdio_probe_dt(&data->pdata, pdev);
>
>
>
>>
>> You will need quilt to apply these patches to the latest Linus release (4.x
>> or 4.x-rcY). The series file is in broken-out.tar.gz and is duplicated in
>> http://ozlabs.org/~akpm/mmotm/series
>>
>> The file broken-out.tar.gz contains two datestamp files: .DATE and
>> .DATE-yyyy-mm-dd-hh-mm-ss. Both contain the string yyyy-mm-dd-hh-mm-ss,
>> followed by the base kernel version against which this patch series is to
>> be applied.
>>
>> This tree is partially included in linux-next. To see which patches are
>> included in linux-next, consult the `series' file. Only the patches
>> within the #NEXT_PATCHES_START/#NEXT_PATCHES_END markers are included in
>> linux-next.
>>
>> A git tree which contains the memory management portion of this tree is
>> maintained at git://git.kernel.org/pub/scm/linux/kernel/git/mhocko/mm.git
>> by Michal Hocko. It contains the patches which are between the
>> "#NEXT_PATCHES_START mm" and "#NEXT_PATCHES_END" markers, from the series
>> file, http://www.ozlabs.org/~akpm/mmotm/series.
>>
>>
>> A full copy of the full kernel tree with the linux-next and mmotm patches
>> already applied is available through git within an hour of the mmotm
>> release. Individual mmotm releases are tagged. The master branch always
>> points to the latest release, so it's constantly rebasing.
>>
>> http://git.cmpxchg.org/cgit.cgi/linux-mmotm.git/
>>
>> To develop on top of mmotm git:
>>
>> $ git remote add mmotm git://git.kernel.org/pub/scm/linux/kernel/git/mhocko/mm.git
>> $ git remote update mmotm
>> $ git checkout -b topic mmotm/master
>> <make changes, commit>
>> $ git send-email mmotm/master.. [...]
>>
>> To rebase a branch with older patches to a new mmotm release:
>>
>> $ git remote update mmotm
>> $ git rebase --onto mmotm/master <topic base> topic
>>
>>
>>
>>
>> The directory http://www.ozlabs.org/~akpm/mmots/ (mm-of-the-second)
>> contains daily snapshots of the -mm tree. It is updated more frequently
>> than mmotm, and is untested.
>>
>> A git copy of this tree is available at
>>
>> http://git.cmpxchg.org/cgit.cgi/linux-mmots.git/
>>
>> and use of this tree is similar to
>> http://git.cmpxchg.org/cgit.cgi/linux-mmotm.git/, described above.
>>
>>
>> This mmotm tree contains the following patches against 4.17-rc6:
>> (patches marked "*" will be included in linux-next)
>>
>
>
--
~Randy
^ permalink raw reply
* Re: [PATCH, net-next] net/mlx5e: fix TLS dependency
From: Saeed Mahameed @ 2018-05-25 23:18 UTC (permalink / raw)
To: davem@davemloft.net, arnd@arndb.de, leon@kernel.org
Cc: linux-kernel@vger.kernel.org, linux-rdma@vger.kernel.org,
Boris Pismenny, Or Gerlitz, Feras Daoud, Ilan Tayari,
netdev@vger.kernel.org, Ilya Lesokhin
In-Reply-To: <20180525213630.2119214-1-arnd@arndb.de>
On Fri, 2018-05-25 at 23:36 +0200, Arnd Bergmann wrote:
> With CONFIG_TLS=m and MLX5_CORE_EN=y, we get a link failure:
>
> drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls_rxtx.o: In
> function `mlx5e_tls_handle_ooo':
> tls_rxtx.c:(.text+0x24c): undefined reference to `tls_get_record'
> drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls_rxtx.o: In
> function `mlx5e_tls_handle_tx_skb':
> tls_rxtx.c:(.text+0x9a8): undefined reference to
> `tls_device_sk_destruct'
>
> This narrows down the dependency to only allow the configurations
> that will actually work. The existing dependency on TLS_DEVICE is
> not sufficient here since MLX5_EN_TLS is a 'bool' symbol.
>
> Fixes: c83294b9efa5 ("net/mlx5e: TLS, Add Innova TLS TX support")
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
LGTM
Acked-by: Saeed Mahameed <saeedm@mellanox.com>
Thank you Arnd!
> drivers/net/ethernet/mellanox/mlx5/core/Kconfig | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
> b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
> index ee6684779d11..2545296a0c08 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
> @@ -91,6 +91,7 @@ config MLX5_EN_TLS
> bool "TLS cryptography-offload accelaration"
> depends on MLX5_CORE_EN
> depends on TLS_DEVICE
> + depends on TLS=y || MLX5_CORE=m
> depends on MLX5_ACCEL
> default n
> ---help---
^ permalink raw reply
* Re: [PATCH net-next v12 2/5] netvsc: refactor notifier/event handling code to use the failover framework
From: Stephen Hemminger @ 2018-05-25 23:28 UTC (permalink / raw)
To: Samudrala, Sridhar
Cc: mst, davem, netdev, virtualization, virtio-dev, jesse.brandeburg,
alexander.h.duyck, kubakici, jasowang, loseweigh, jiri,
aaron.f.brown, anjali.singhai
In-Reply-To: <c0be8e44-34f8-0e46-3a51-7ce869a5d351@intel.com>
On Fri, 25 May 2018 16:11:47 -0700
"Samudrala, Sridhar" <sridhar.samudrala@intel.com> wrote:
> On 5/25/2018 3:34 PM, Stephen Hemminger wrote:
> > On Thu, 24 May 2018 09:55:14 -0700
> > Sridhar Samudrala <sridhar.samudrala@intel.com> wrote:
> >
> >> --- a/drivers/net/hyperv/Kconfig
> >> +++ b/drivers/net/hyperv/Kconfig
> >> @@ -2,5 +2,6 @@ config HYPERV_NET
> >> tristate "Microsoft Hyper-V virtual network driver"
> >> depends on HYPERV
> >> select UCS2_STRING
> >> + select FAILOVER
> > When I take a working kernel config, add the patches then do
> > make oldconfig
> >
> > It is not autoselecting FAILOVER, it prompts me for it. This means
> > if user says no then a non-working netvsc device is made.
>
> I see
> Generic failover module (FAILOVER) [M/y/?] (NEW)
>
> So the user is given an option to either build as a Module or part of the
> kernel. 'n' is not an option.
With most libraries there is no prompt at all.
^ permalink raw reply
* Confusion about (new?) bridge behavior
From: Florian Fainelli @ 2018-05-25 23:49 UTC (permalink / raw)
To: netdev, nikolay, arkadis, ivecera, jiri; +Cc: vivien.didelot, andrew
Hi,
The DSA b53 driver currently (well, not quite currently, but at some
point) was forcing the CPU port VLAN membership to be tagged. The reason
for that is mostly because if we allow the CPU port to be untagged in
multiple VLANs we can't quite properly separate traffic at the CPU port
level, so we don't do that.
At some point v4.12, or maybe as far back as 4.9, I remember the
following from happening:
- it was not necessary to turn on vlan_filtering on the bridge to get
the DSA layer to program VLAN entries into the switch, I only get those
calls now if vlan_filtering is enabled, this is not a big issue, but I
do wonder if something did change here? Could be a DSA specific issue
here, I can bisect that later
- because the CPU port was configured tagged into VLAN 1, it was
necessary to either change the default bridge master device settings
(default being VID 1 pvid untagged) to pop the VLAN tag, and conversely
push the VLAN tag on egress path and/or create a network device such
that would be responsible for terminating the VLAN tag, e.g: br0.1
But now, this does not seem to be necessary and I just can't explain
why, it might very well be a switch driver configuration issue.
Now what I am seeing is the following:
1) Default configuration with vlan_filtering = 1
# bridge vlan show
port vlan ids
gphy 1 PVID Egress Untagged
br0 1 PVID Egress Untagged
If I look at the CPU port, I can see that frames from switch to CPU have
VLAN tag 1, which is expected, yet frames that are from CPU to switch do
not have such a VLAN tag 1, and yet things work okay, dhcp + ping using
br0 work just fine. I suppose that is because of the pvid behavior which
assigns untagged frames to the default VLAN which happens to be 1 in
that case.
2) Changing the bridge to be in VLAN 1 no pvid, no untagged, still with
vlan_filtering = 1
# bridge vlan add vid 1 dev br0 self
# bridge vlan show
port vlan ids
gphy 1 PVID Egress Untagged
br0 1
The frames from switch to CPU still have VLAN tag 1, now I need to
create a br0.1 device to insert the VLAN tag for dhcp + ping to work
using br0.1 in that case, though I still do not see the VLAN tag being
present for frames that are from CPU to switch...
Was I hallucinating before and things were equally broken, or did
something change recently?
Thank you!
--
Florian
^ permalink raw reply
* Re: aio poll and a new in-kernel poll API V13
From: Al Viro @ 2018-05-26 0:11 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Avi Kivity, linux-aio, linux-fsdevel, netdev, linux-api,
linux-kernel
In-Reply-To: <20180523192022.1703-1-hch@lst.de>
On Wed, May 23, 2018 at 09:19:49PM +0200, Christoph Hellwig wrote:
> Hi all,
>
> this series adds support for the IOCB_CMD_POLL operation to poll for the
> readyness of file descriptors using the aio subsystem. The API is based
> on patches that existed in RHAS2.1 and RHEL3, which means it already is
> supported by libaio. To implement the poll support efficiently new
> methods to poll are introduced in struct file_operations: get_poll_head
> and poll_mask. The first one returns a wait_queue_head to wait on
> (lifetime is bound by the file), and the second does a non-blocking
> check for the POLL* events. This allows aio poll to work without
> any additional context switches, unlike epoll.
>
> This series sits on top of the aio-fsync series that also includes
> support for io_pgetevents.
OK, I can live with that, except for one problem - the first patch shouldn't
be sitting on top of arseloads of next window fodder.
Please, rebase the rest of the series on top of merge of vfs.git#fixes
(4faa99965e02) with your aio-fsync.4 and tell me what to pull.
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in
the body to majordomo@kvack.org. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"aart@kvack.org">aart@kvack.org</a>
^ permalink raw reply
* Re: [PATCH, net-next] qcom-emag: hide ACPI specific functions
From: Timur Tabi @ 2018-05-26 0:22 UTC (permalink / raw)
To: Arnd Bergmann, David S. Miller; +Cc: Hemanth Puranik, netdev, linux-kernel
In-Reply-To: <20180525213714.2120604-1-arnd@arndb.de>
On 5/25/18 4:37 PM, Arnd Bergmann wrote:
> +#ifdef CONFIG_ACPI
> static int emac_sgmii_irq_clear(struct emac_adapter *adpt, u8 irq_bits)
> {
> struct emac_sgmii *phy = &adpt->phy;
> @@ -288,6 +289,7 @@ static struct sgmii_ops qdf2400_ops = {
> .link_change = emac_sgmii_common_link_change,
> .reset = emac_sgmii_common_reset,
> };
> +#endif
This seems wrong. The SGMII interrupt handler should still be viable on
a device-tree system. There is a DT compatibility entry for the qdf2432.
Looks like that most recent patch on net-next broke DT support, when it
removed these lines:
- phy->open = emac_sgmii_open;
- phy->close = emac_sgmii_close;
- phy->link_up = emac_sgmii_link_up;
- phy->link_down = emac_sgmii_link_down;
I'll take it look at it next week when I'm back in the office.
--
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm
Technologies, Inc. Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply
* [pull request][for-next 00/12] Mellanox, mlx5e updates 2018-05-25
From: Saeed Mahameed @ 2018-05-26 0:01 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Saeed Mahameed
Hi dave,
This is a mlx5e only pull request, for more information please see tag
log below.
Please pull and let me know if there's any problem.
Thanks,
Saeed.
----
The following changes since commit e52cde71709348c0d67bf0f213b438fa4d6cf9a9:
net: dsa: dsa_loop: Make dynamic debugging helpful (2018-05-25 16:46:29 -0400)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux.git tags/mlx5e-updates-2018-05-25
for you to fetch changes up to 05909babce5328f468f7ac3a1033431c895f97a5:
net/mlx5e: Avoid reset netdev stats on configuration changes (2018-05-25 16:14:28 -0700)
----------------------------------------------------------------
mlx5e-updates-2018-05-25
This series includes updates for mlx5e netdev driver.
1) Allowr flow based VF vport mirroring under sriov switchdev scheme,
added support for offloading the TC mirred mirror sub-action, from
Chris Mi.
=================
From: Or Gerlitz <ogerlitz@mellanox.com>
The user will typically set the actions order such that the mirror
port (mirror VF) sees packets as the original port (VF under
mirroring) sent them or as it will receive them. In the general case,
it means that packets are potentially sent to the mirror port before
or after some actions were applied on them.
To properly do that, we follow on the exact action order as set for
the flow and make sure this will also be the case when we program the
HW offload.
If all the actions should apply before forwarding to the mirror and dest port,
mirroring is just multicasting to the two vports. Otherwise, we split
the TC flow to two HW rules, where the 1st applies only the actions
needed up to the mirror (if there are such) and the 2nd the rest of
the actions plus the forwarding to the dest vport.
=================
2) Move to order-0 only allocations (using fragmented work queues) for all
work queues used by the driver, RX and TX descriptor rings
(RQs, SQs and Completion Queues (CQs)), from Tariq Toukan.
3) Avoid resetting netdevice statistics on netdevice
state changes, from Eran Ben Elisha.
----------------------------------------------------------------
Chris Mi (5):
net/mlx5: E-Switch, Reorganize and rename fdb flow tables
net/mlx5: Add cap bits for flow table destination in FDB table
net/mlx5: E-switch, Create a second level FDB flow table
net/mlx5e: Parse mirroring action for offloaded TC eswitch flows
net/mlx5e: Split offloaded eswitch TC rules for port mirroring
Eran Ben Elisha (1):
net/mlx5e: Avoid reset netdev stats on configuration changes
Saeed Mahameed (1):
net/mlx5e: Move phy link down events counter out of SW stats
Shalom Lagziel (1):
net/mlx5e: Introducing new statistics rwlock
Tariq Toukan (4):
net/mlx5e: Use WQ API functions instead of direct fields access
net/mlx5e: TX, Use actual WQE size for SQ edge fill
net/mlx5i: Use compilation flag in IPOIB header
net/mlx5: Use order-0 allocations for all WQ types
drivers/net/ethernet/mellanox/mlx5/core/en.h | 30 ++-
.../mellanox/mlx5/core/en_accel/tls_rxtx.c | 4 +-
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 88 ++++---
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 20 +-
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 126 ++++++----
drivers/net/ethernet/mellanox/mlx5/core/en_stats.c | 101 ++++----
drivers/net/ethernet/mellanox/mlx5/core/en_stats.h | 5 +-
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 83 +++++--
drivers/net/ethernet/mellanox/mlx5/core/en_tx.c | 262 +++++++++++++--------
drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c | 6 +-
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 22 +-
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h | 23 +-
.../ethernet/mellanox/mlx5/core/eswitch_offloads.c | 133 ++++++++---
.../net/ethernet/mellanox/mlx5/core/fpga/conn.c | 14 +-
.../net/ethernet/mellanox/mlx5/core/fpga/conn.h | 2 +-
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 2 +-
.../net/ethernet/mellanox/mlx5/core/ipoib/ipoib.h | 26 ++
drivers/net/ethernet/mellanox/mlx5/core/wq.c | 94 +++++---
drivers/net/ethernet/mellanox/mlx5/core/wq.h | 50 ++--
include/linux/mlx5/driver.h | 16 +-
include/linux/mlx5/mlx5_ifc.h | 4 +-
21 files changed, 724 insertions(+), 387 deletions(-)
^ permalink raw reply
* [for-next 01/12] net/mlx5: E-Switch, Reorganize and rename fdb flow tables
From: Saeed Mahameed @ 2018-05-26 0:01 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Chris Mi, Saeed Mahameed
In-Reply-To: <20180526000207.19568-1-saeedm@mellanox.com>
From: Chris Mi <chrism@mellanox.com>
We have several fdb flow tables for each of the legacy and switchdev
modes. In the switchdev mode, there are fast path and slow path flow
tables. Towards adding more flow tables in upcoming patches, reorganize
and rename the various existing ones to reflect their functionality.
Signed-off-by: Chris Mi <chrism@mellanox.com>
Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
.../net/ethernet/mellanox/mlx5/core/eswitch.c | 22 +++++++++----------
.../net/ethernet/mellanox/mlx5/core/eswitch.h | 5 +++--
.../mellanox/mlx5/core/eswitch_offloads.c | 22 +++++++++----------
3 files changed, 25 insertions(+), 24 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
index 09f0e11c6ffc..6cab1dd66d1b 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
@@ -200,7 +200,7 @@ __esw_fdb_set_vport_rule(struct mlx5_eswitch *esw, u32 vport, bool rx_rule,
spec->match_criteria_enable = match_header;
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
flow_rule =
- mlx5_add_flow_rules(esw->fdb_table.fdb, spec,
+ mlx5_add_flow_rules(esw->fdb_table.legacy.fdb, spec,
&flow_act, &dest, 1);
if (IS_ERR(flow_rule)) {
esw_warn(esw->dev,
@@ -282,7 +282,7 @@ static int esw_create_legacy_fdb_table(struct mlx5_eswitch *esw, int nvports)
esw_warn(dev, "Failed to create FDB Table err %d\n", err);
goto out;
}
- esw->fdb_table.fdb = fdb;
+ esw->fdb_table.legacy.fdb = fdb;
/* Addresses group : Full match unicast/multicast addresses */
MLX5_SET(create_flow_group_in, flow_group_in, match_criteria_enable,
@@ -343,9 +343,9 @@ static int esw_create_legacy_fdb_table(struct mlx5_eswitch *esw, int nvports)
mlx5_destroy_flow_group(esw->fdb_table.legacy.addr_grp);
esw->fdb_table.legacy.addr_grp = NULL;
}
- if (!IS_ERR_OR_NULL(esw->fdb_table.fdb)) {
- mlx5_destroy_flow_table(esw->fdb_table.fdb);
- esw->fdb_table.fdb = NULL;
+ if (!IS_ERR_OR_NULL(esw->fdb_table.legacy.fdb)) {
+ mlx5_destroy_flow_table(esw->fdb_table.legacy.fdb);
+ esw->fdb_table.legacy.fdb = NULL;
}
}
@@ -355,15 +355,15 @@ static int esw_create_legacy_fdb_table(struct mlx5_eswitch *esw, int nvports)
static void esw_destroy_legacy_fdb_table(struct mlx5_eswitch *esw)
{
- if (!esw->fdb_table.fdb)
+ if (!esw->fdb_table.legacy.fdb)
return;
esw_debug(esw->dev, "Destroy FDB Table\n");
mlx5_destroy_flow_group(esw->fdb_table.legacy.promisc_grp);
mlx5_destroy_flow_group(esw->fdb_table.legacy.allmulti_grp);
mlx5_destroy_flow_group(esw->fdb_table.legacy.addr_grp);
- mlx5_destroy_flow_table(esw->fdb_table.fdb);
- esw->fdb_table.fdb = NULL;
+ mlx5_destroy_flow_table(esw->fdb_table.legacy.fdb);
+ esw->fdb_table.legacy.fdb = NULL;
esw->fdb_table.legacy.addr_grp = NULL;
esw->fdb_table.legacy.allmulti_grp = NULL;
esw->fdb_table.legacy.promisc_grp = NULL;
@@ -396,7 +396,7 @@ static int esw_add_uc_addr(struct mlx5_eswitch *esw, struct vport_addr *vaddr)
fdb_add:
/* SRIOV is enabled: Forward UC MAC to vport */
- if (esw->fdb_table.fdb && esw->mode == SRIOV_LEGACY)
+ if (esw->fdb_table.legacy.fdb && esw->mode == SRIOV_LEGACY)
vaddr->flow_rule = esw_fdb_set_vport_rule(esw, mac, vport);
esw_debug(esw->dev, "\tADDED UC MAC: vport[%d] %pM fr(%p)\n",
@@ -486,7 +486,7 @@ static int esw_add_mc_addr(struct mlx5_eswitch *esw, struct vport_addr *vaddr)
u8 *mac = vaddr->node.addr;
u32 vport = vaddr->vport;
- if (!esw->fdb_table.fdb)
+ if (!esw->fdb_table.legacy.fdb)
return 0;
esw_mc = l2addr_hash_find(hash, mac, struct esw_mc_addr);
@@ -526,7 +526,7 @@ static int esw_del_mc_addr(struct mlx5_eswitch *esw, struct vport_addr *vaddr)
u8 *mac = vaddr->node.addr;
u32 vport = vaddr->vport;
- if (!esw->fdb_table.fdb)
+ if (!esw->fdb_table.legacy.fdb)
return 0;
esw_mc = l2addr_hash_find(hash, mac, struct esw_mc_addr);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
index f47a14e31b7d..d1a3f7fcca1c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
@@ -117,16 +117,17 @@ struct mlx5_vport {
};
struct mlx5_eswitch_fdb {
- void *fdb;
union {
struct legacy_fdb {
+ struct mlx5_flow_table *fdb;
struct mlx5_flow_group *addr_grp;
struct mlx5_flow_group *allmulti_grp;
struct mlx5_flow_group *promisc_grp;
} legacy;
struct offloads_fdb {
- struct mlx5_flow_table *fdb;
+ struct mlx5_flow_table *fast_fdb;
+ struct mlx5_flow_table *slow_fdb;
struct mlx5_flow_group *send_to_vport_grp;
struct mlx5_flow_group *miss_grp;
struct mlx5_flow_handle *miss_rule_uni;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
index b9ea464bcfa9..bb8eac5523a7 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
@@ -119,7 +119,7 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_ENCAP)
flow_act.encap_id = attr->encap_id;
- rule = mlx5_add_flow_rules((struct mlx5_flow_table *)esw->fdb_table.fdb,
+ rule = mlx5_add_flow_rules((struct mlx5_flow_table *)esw->fdb_table.offloads.fast_fdb,
spec, &flow_act, dest, i);
if (IS_ERR(rule))
goto err_add_rule;
@@ -363,7 +363,7 @@ mlx5_eswitch_add_send_to_vport_rule(struct mlx5_eswitch *esw, int vport, u32 sqn
dest.vport.num = vport;
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
- flow_rule = mlx5_add_flow_rules(esw->fdb_table.offloads.fdb, spec,
+ flow_rule = mlx5_add_flow_rules(esw->fdb_table.offloads.slow_fdb, spec,
&flow_act, &dest, 1);
if (IS_ERR(flow_rule))
esw_warn(esw->dev, "FDB: Failed to add send to vport rule err %ld\n", PTR_ERR(flow_rule));
@@ -407,7 +407,7 @@ static int esw_add_fdb_miss_rule(struct mlx5_eswitch *esw)
dest.vport.num = 0;
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
- flow_rule = mlx5_add_flow_rules(esw->fdb_table.offloads.fdb, spec,
+ flow_rule = mlx5_add_flow_rules(esw->fdb_table.offloads.slow_fdb, spec,
&flow_act, &dest, 1);
if (IS_ERR(flow_rule)) {
err = PTR_ERR(flow_rule);
@@ -422,7 +422,7 @@ static int esw_add_fdb_miss_rule(struct mlx5_eswitch *esw)
dmac_v = MLX5_ADDR_OF(fte_match_param, headers_v,
outer_headers.dmac_47_16);
dmac_v[0] = 0x01;
- flow_rule = mlx5_add_flow_rules(esw->fdb_table.offloads.fdb, spec,
+ flow_rule = mlx5_add_flow_rules(esw->fdb_table.offloads.slow_fdb, spec,
&flow_act, &dest, 1);
if (IS_ERR(flow_rule)) {
err = PTR_ERR(flow_rule);
@@ -476,7 +476,7 @@ static int esw_create_offloads_fast_fdb_table(struct mlx5_eswitch *esw)
esw_warn(dev, "Failed to create Fast path FDB Table err %d\n", err);
goto out;
}
- esw->fdb_table.fdb = fdb;
+ esw->fdb_table.offloads.fast_fdb = fdb;
out:
return err;
@@ -484,7 +484,7 @@ static int esw_create_offloads_fast_fdb_table(struct mlx5_eswitch *esw)
static void esw_destroy_offloads_fast_fdb_table(struct mlx5_eswitch *esw)
{
- mlx5_destroy_flow_table(esw->fdb_table.fdb);
+ mlx5_destroy_flow_table(esw->fdb_table.offloads.fast_fdb);
}
#define MAX_PF_SQ 256
@@ -530,7 +530,7 @@ static int esw_create_offloads_fdb_tables(struct mlx5_eswitch *esw, int nvports)
esw_warn(dev, "Failed to create slow path FDB Table err %d\n", err);
goto slow_fdb_err;
}
- esw->fdb_table.offloads.fdb = fdb;
+ esw->fdb_table.offloads.slow_fdb = fdb;
/* create send-to-vport group */
memset(flow_group_in, 0, inlen);
@@ -586,9 +586,9 @@ static int esw_create_offloads_fdb_tables(struct mlx5_eswitch *esw, int nvports)
miss_err:
mlx5_destroy_flow_group(esw->fdb_table.offloads.send_to_vport_grp);
send_vport_err:
- mlx5_destroy_flow_table(esw->fdb_table.offloads.fdb);
+ mlx5_destroy_flow_table(esw->fdb_table.offloads.slow_fdb);
slow_fdb_err:
- mlx5_destroy_flow_table(esw->fdb_table.fdb);
+ mlx5_destroy_flow_table(esw->fdb_table.offloads.fast_fdb);
fast_fdb_err:
ns_err:
kvfree(flow_group_in);
@@ -597,7 +597,7 @@ static int esw_create_offloads_fdb_tables(struct mlx5_eswitch *esw, int nvports)
static void esw_destroy_offloads_fdb_tables(struct mlx5_eswitch *esw)
{
- if (!esw->fdb_table.fdb)
+ if (!esw->fdb_table.offloads.fast_fdb)
return;
esw_debug(esw->dev, "Destroy offloads FDB Tables\n");
@@ -606,7 +606,7 @@ static void esw_destroy_offloads_fdb_tables(struct mlx5_eswitch *esw)
mlx5_destroy_flow_group(esw->fdb_table.offloads.send_to_vport_grp);
mlx5_destroy_flow_group(esw->fdb_table.offloads.miss_grp);
- mlx5_destroy_flow_table(esw->fdb_table.offloads.fdb);
+ mlx5_destroy_flow_table(esw->fdb_table.offloads.slow_fdb);
esw_destroy_offloads_fast_fdb_table(esw);
}
--
2.17.0
^ permalink raw reply related
* [for-next 02/12] net/mlx5: Add cap bits for flow table destination in FDB table
From: Saeed Mahameed @ 2018-05-26 0:01 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Chris Mi, Saeed Mahameed
In-Reply-To: <20180526000207.19568-1-saeedm@mellanox.com>
From: Chris Mi <chrism@mellanox.com>
If set, the FDB table supports the forward action with a
destination list that includes a flow table.
Signed-off-by: Chris Mi <chrism@mellanox.com>
Reviewed-by: Paul Blakey <paulb@mellanox.com>
Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
include/linux/mlx5/mlx5_ifc.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index edbddeaacc88..05b480fae27d 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -524,7 +524,9 @@ struct mlx5_ifc_flow_table_nic_cap_bits {
};
struct mlx5_ifc_flow_table_eswitch_cap_bits {
- u8 reserved_at_0[0x200];
+ u8 reserved_at_0[0x1c];
+ u8 fdb_multi_path_to_table[0x1];
+ u8 reserved_at_1d[0x1e3];
struct mlx5_ifc_flow_table_prop_layout_bits flow_table_properties_nic_esw_fdb;
--
2.17.0
^ permalink raw reply related
* [for-next 03/12] net/mlx5: E-switch, Create a second level FDB flow table
From: Saeed Mahameed @ 2018-05-26 0:01 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Chris Mi, Saeed Mahameed
In-Reply-To: <20180526000207.19568-1-saeedm@mellanox.com>
From: Chris Mi <chrism@mellanox.com>
If firmware supports the forward action with a destination list
that includes a flow table, create a second level FDB flow table.
This is going to be used for flow based mirroring under the switchdev
offloads mode.
Signed-off-by: Chris Mi <chrism@mellanox.com>
Reviewed-by: Paul Blakey <paulb@mellanox.com>
Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
.../net/ethernet/mellanox/mlx5/core/eswitch.h | 4 +++
.../mellanox/mlx5/core/eswitch_offloads.c | 31 ++++++++++++++++---
.../net/ethernet/mellanox/mlx5/core/fs_core.c | 2 +-
3 files changed, 32 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
index d1a3f7fcca1c..d06c11629121 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
@@ -55,6 +55,9 @@
#define MLX5_RATE_TO_BW_SHARE(rate, divider, limit) \
min_t(u32, max_t(u32, (rate) / (divider), MLX5_MIN_BW_SHARE), limit)
+#define mlx5_esw_has_fwd_fdb(dev) \
+ MLX5_CAP_ESW_FLOWTABLE(dev, fdb_multi_path_to_table)
+
struct vport_ingress {
struct mlx5_flow_table *acl;
struct mlx5_flow_group *allow_untagged_spoofchk_grp;
@@ -127,6 +130,7 @@ struct mlx5_eswitch_fdb {
struct offloads_fdb {
struct mlx5_flow_table *fast_fdb;
+ struct mlx5_flow_table *fwd_fdb;
struct mlx5_flow_table *slow_fdb;
struct mlx5_flow_group *send_to_vport_grp;
struct mlx5_flow_group *miss_grp;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
index bb8eac5523a7..8ea11f24380c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
@@ -454,7 +454,7 @@ static int esw_create_offloads_fast_fdb_table(struct mlx5_eswitch *esw)
if (!root_ns) {
esw_warn(dev, "Failed to get FDB flow namespace\n");
err = -EOPNOTSUPP;
- goto out;
+ goto out_namespace;
}
esw_debug(dev, "Create offloads FDB table, min (max esw size(2^%d), max counters(%d)*groups(%d))\n",
@@ -464,6 +464,9 @@ static int esw_create_offloads_fast_fdb_table(struct mlx5_eswitch *esw)
esw_size = min_t(int, max_flow_counter * ESW_OFFLOADS_NUM_GROUPS,
1 << MLX5_CAP_ESW_FLOWTABLE_FDB(dev, log_max_ft_size));
+ if (mlx5_esw_has_fwd_fdb(dev))
+ esw_size >>= 1;
+
if (esw->offloads.encap != DEVLINK_ESWITCH_ENCAP_MODE_NONE)
flags |= MLX5_FLOW_TABLE_TUNNEL_EN;
@@ -474,16 +477,36 @@ static int esw_create_offloads_fast_fdb_table(struct mlx5_eswitch *esw)
if (IS_ERR(fdb)) {
err = PTR_ERR(fdb);
esw_warn(dev, "Failed to create Fast path FDB Table err %d\n", err);
- goto out;
+ goto out_namespace;
}
esw->fdb_table.offloads.fast_fdb = fdb;
-out:
+ if (!mlx5_esw_has_fwd_fdb(dev))
+ goto out_namespace;
+
+ fdb = mlx5_create_auto_grouped_flow_table(root_ns, FDB_FAST_PATH,
+ esw_size,
+ ESW_OFFLOADS_NUM_GROUPS, 1,
+ flags);
+ if (IS_ERR(fdb)) {
+ err = PTR_ERR(fdb);
+ esw_warn(dev, "Failed to create fwd table err %d\n", err);
+ goto out_ft;
+ }
+ esw->fdb_table.offloads.fwd_fdb = fdb;
+
+ return err;
+
+out_ft:
+ mlx5_destroy_flow_table(esw->fdb_table.offloads.fast_fdb);
+out_namespace:
return err;
}
static void esw_destroy_offloads_fast_fdb_table(struct mlx5_eswitch *esw)
{
+ if (mlx5_esw_has_fwd_fdb(esw->dev))
+ mlx5_destroy_flow_table(esw->fdb_table.offloads.fwd_fdb);
mlx5_destroy_flow_table(esw->fdb_table.offloads.fast_fdb);
}
@@ -588,7 +611,7 @@ static int esw_create_offloads_fdb_tables(struct mlx5_eswitch *esw, int nvports)
send_vport_err:
mlx5_destroy_flow_table(esw->fdb_table.offloads.slow_fdb);
slow_fdb_err:
- mlx5_destroy_flow_table(esw->fdb_table.offloads.fast_fdb);
+ esw_destroy_offloads_fast_fdb_table(esw);
fast_fdb_err:
ns_err:
kvfree(flow_group_in);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
index 806e95523f9e..f9c2c03083eb 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
@@ -2495,7 +2495,7 @@ static int init_fdb_root_ns(struct mlx5_flow_steering *steering)
if (!steering->fdb_root_ns)
return -ENOMEM;
- prio = fs_create_prio(&steering->fdb_root_ns->ns, 0, 1);
+ prio = fs_create_prio(&steering->fdb_root_ns->ns, 0, 2);
if (IS_ERR(prio))
goto out_err;
--
2.17.0
^ permalink raw reply related
* [for-next 04/12] net/mlx5e: Parse mirroring action for offloaded TC eswitch flows
From: Saeed Mahameed @ 2018-05-26 0:01 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Chris Mi, Saeed Mahameed
In-Reply-To: <20180526000207.19568-1-saeedm@mellanox.com>
From: Chris Mi <chrism@mellanox.com>
Currently, we only support the mirred redirect TC sub-action. In order
to support flow based vport mirroring, add support to parse the mirred
mirror sub-action.
For mirroring, user-space will typically set the action order such that
the mirror port (mirror VF) sees packets as the original port (VF under
mirroring) sent them or as it will receive them.
In the general case, it means that packets are potentially sent to the
mirror port before or after some actions were applied on them. To
properly do that, we should follow on the exact action order as set for
the flow and make sure this will also be the case when we program the HW
offload.
We introduce a counter for the output ports (attr->out_count), which we
increase when parsing each mirred redirect/mirror sub-action and when
dealing with encap.
We introduce a counter (attr->mirror_count) telling us if split is
needed. If no split is needed and mirroring is just multicasting to
vport, the mirror count is zero, all the actions of the TC flow should
apply on that single HW flow.
If split is needed, the mirror count tells where to do the split, all
non-mirred tc actions should apply only after the split.
The mirror count is set while parsing the following actions encap/decap,
header re-write, vlan push/pop.
Signed-off-by: Chris Mi <chrism@mellanox.com>
Reviewed-by: Paul Blakey <paulb@mellanox.com>
Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
.../net/ethernet/mellanox/mlx5/core/en_tc.c | 26 +++++++++++++----
.../net/ethernet/mellanox/mlx5/core/eswitch.h | 10 +++++--
.../mellanox/mlx5/core/eswitch_offloads.c | 28 ++++++++++---------
3 files changed, 43 insertions(+), 21 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index a9c96fe8e4fe..302c5500f9ad 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -844,8 +844,8 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
}
out_priv = netdev_priv(encap_dev);
rpriv = out_priv->ppriv;
- attr->out_rep = rpriv->rep;
- attr->out_mdev = out_priv->mdev;
+ attr->out_rep[attr->out_count] = rpriv->rep;
+ attr->out_mdev[attr->out_count++] = out_priv->mdev;
}
err = mlx5_eswitch_add_vlan_action(esw, attr);
@@ -2537,6 +2537,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
return err;
action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
+ attr->mirror_count = attr->out_count;
continue;
}
@@ -2548,12 +2549,18 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
return -EOPNOTSUPP;
}
- if (is_tcf_mirred_egress_redirect(a)) {
- struct net_device *out_dev;
+ if (is_tcf_mirred_egress_redirect(a) || is_tcf_mirred_egress_mirror(a)) {
struct mlx5e_priv *out_priv;
+ struct net_device *out_dev;
out_dev = tcf_mirred_dev(a);
+ if (attr->out_count >= MLX5_MAX_FLOW_FWD_VPORTS) {
+ pr_err("can't support more than %d output ports, can't offload forwarding\n",
+ attr->out_count);
+ return -EOPNOTSUPP;
+ }
+
if (switchdev_port_same_parent_id(priv->netdev,
out_dev) ||
is_merged_eswitch_dev(priv, out_dev)) {
@@ -2561,8 +2568,8 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
MLX5_FLOW_CONTEXT_ACTION_COUNT;
out_priv = netdev_priv(out_dev);
rpriv = out_priv->ppriv;
- attr->out_rep = rpriv->rep;
- attr->out_mdev = out_priv->mdev;
+ attr->out_rep[attr->out_count] = rpriv->rep;
+ attr->out_mdev[attr->out_count++] = out_priv->mdev;
} else if (encap) {
parse_attr->mirred_ifindex = out_dev->ifindex;
parse_attr->tun_info = *info;
@@ -2585,6 +2592,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
encap = true;
else
return -EOPNOTSUPP;
+ attr->mirror_count = attr->out_count;
continue;
}
@@ -2606,6 +2614,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
} else { /* action is TCA_VLAN_ACT_MODIFY */
return -EOPNOTSUPP;
}
+ attr->mirror_count = attr->out_count;
continue;
}
@@ -2621,6 +2630,11 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
if (!actions_match_supported(priv, exts, parse_attr, flow))
return -EOPNOTSUPP;
+ if (attr->out_count > 1 && !mlx5_esw_has_fwd_fdb(priv->mdev)) {
+ netdev_warn_once(priv->netdev, "current firmware doesn't support split rule for port mirroring\n");
+ return -EOPNOTSUPP;
+ }
+
return 0;
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
index d06c11629121..386b0e354c41 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
@@ -239,12 +239,18 @@ enum mlx5_flow_match_level {
MLX5_MATCH_L4 = MLX5_INLINE_MODE_TCP_UDP,
};
+/* current maximum for flow based vport multicasting */
+#define MLX5_MAX_FLOW_FWD_VPORTS 2
+
struct mlx5_esw_flow_attr {
struct mlx5_eswitch_rep *in_rep;
- struct mlx5_eswitch_rep *out_rep;
- struct mlx5_core_dev *out_mdev;
+ struct mlx5_eswitch_rep *out_rep[MLX5_MAX_FLOW_FWD_VPORTS];
+ struct mlx5_core_dev *out_mdev[MLX5_MAX_FLOW_FWD_VPORTS];
struct mlx5_core_dev *in_mdev;
+ int mirror_count;
+ int out_count;
+
int action;
__be16 vlan_proto;
u16 vlan_vid;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
index 8ea11f24380c..7db8b9a41925 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
@@ -48,12 +48,12 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
struct mlx5_flow_spec *spec,
struct mlx5_esw_flow_attr *attr)
{
- struct mlx5_flow_destination dest[2] = {};
+ struct mlx5_flow_destination dest[MLX5_MAX_FLOW_FWD_VPORTS + 1] = {};
struct mlx5_flow_act flow_act = {0};
struct mlx5_fc *counter = NULL;
struct mlx5_flow_handle *rule;
+ int j, i = 0;
void *misc;
- int i = 0;
if (esw->mode != SRIOV_OFFLOADS)
return ERR_PTR(-EOPNOTSUPP);
@@ -70,14 +70,16 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
}
if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) {
- dest[i].type = MLX5_FLOW_DESTINATION_TYPE_VPORT;
- dest[i].vport.num = attr->out_rep->vport;
- if (MLX5_CAP_ESW(esw->dev, merged_eswitch)) {
- dest[i].vport.vhca_id =
- MLX5_CAP_GEN(attr->out_mdev, vhca_id);
- dest[i].vport.vhca_id_valid = 1;
+ for (j = attr->mirror_count; j < attr->out_count; j++) {
+ dest[i].type = MLX5_FLOW_DESTINATION_TYPE_VPORT;
+ dest[i].vport.num = attr->out_rep[j]->vport;
+ if (MLX5_CAP_ESW(esw->dev, merged_eswitch)) {
+ dest[i].vport.vhca_id =
+ MLX5_CAP_GEN(attr->out_mdev[j], vhca_id);
+ dest[i].vport.vhca_id_valid = 1;
+ }
+ i++;
}
- i++;
}
if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_COUNT) {
counter = mlx5_fc_create(esw->dev, true);
@@ -173,7 +175,7 @@ esw_vlan_action_get_vport(struct mlx5_esw_flow_attr *attr, bool push, bool pop)
struct mlx5_eswitch_rep *in_rep, *out_rep, *vport = NULL;
in_rep = attr->in_rep;
- out_rep = attr->out_rep;
+ out_rep = attr->out_rep[0];
if (push)
vport = in_rep;
@@ -194,7 +196,7 @@ static int esw_add_vlan_action_check(struct mlx5_esw_flow_attr *attr,
goto out_notsupp;
in_rep = attr->in_rep;
- out_rep = attr->out_rep;
+ out_rep = attr->out_rep[0];
if (push && in_rep->vport == FDB_UPLINK_VPORT)
goto out_notsupp;
@@ -245,7 +247,7 @@ int mlx5_eswitch_add_vlan_action(struct mlx5_eswitch *esw,
if (!push && !pop && fwd) {
/* tracks VF --> wire rules without vlan push action */
- if (attr->out_rep->vport == FDB_UPLINK_VPORT) {
+ if (attr->out_rep[0]->vport == FDB_UPLINK_VPORT) {
vport->vlan_refcount++;
attr->vlan_handled = true;
}
@@ -305,7 +307,7 @@ int mlx5_eswitch_del_vlan_action(struct mlx5_eswitch *esw,
if (!push && !pop && fwd) {
/* tracks VF --> wire rules without vlan push action */
- if (attr->out_rep->vport == FDB_UPLINK_VPORT)
+ if (attr->out_rep[0]->vport == FDB_UPLINK_VPORT)
vport->vlan_refcount--;
return 0;
--
2.17.0
^ permalink raw reply related
* [for-next 05/12] net/mlx5e: Split offloaded eswitch TC rules for port mirroring
From: Saeed Mahameed @ 2018-05-26 0:02 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Chris Mi, Saeed Mahameed
In-Reply-To: <20180526000207.19568-1-saeedm@mellanox.com>
From: Chris Mi <chrism@mellanox.com>
If a TC rule needs to be split for mirroring, create two HW rules,
in the first level and the second level flow tables accordingly.
In the first level flow table, forward the packet to the mirror
port and forward the packet to the second level flow table for
further processing, eg. encap, vlan push or header re-write.
Currently the matching is repeated in both stages.
While here, simplify the setup of the vhca id valid indicator also
in the existing code.
Signed-off-by: Chris Mi <chrism@mellanox.com>
Reviewed-by: Paul Blakey <paulb@mellanox.com>
Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
.../net/ethernet/mellanox/mlx5/core/en_tc.c | 57 ++++++++++++----
.../net/ethernet/mellanox/mlx5/core/eswitch.h | 4 ++
.../mellanox/mlx5/core/eswitch_offloads.c | 68 +++++++++++++++++--
3 files changed, 108 insertions(+), 21 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index 302c5500f9ad..9372d914abe5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -75,12 +75,14 @@ enum {
MLX5E_TC_FLOW_HAIRPIN_RSS = BIT(MLX5E_TC_FLOW_BASE + 4),
};
+#define MLX5E_TC_MAX_SPLITS 1
+
struct mlx5e_tc_flow {
struct rhash_head node;
struct mlx5e_priv *priv;
u64 cookie;
u8 flags;
- struct mlx5_flow_handle *rule;
+ struct mlx5_flow_handle *rule[MLX5E_TC_MAX_SPLITS + 1];
struct list_head encap; /* flows sharing the same encap ID */
struct list_head mod_hdr; /* flows sharing the same mod hdr ID */
struct list_head hairpin; /* flows sharing the same hairpin */
@@ -794,8 +796,8 @@ static void mlx5e_tc_del_nic_flow(struct mlx5e_priv *priv,
struct mlx5_nic_flow_attr *attr = flow->nic_attr;
struct mlx5_fc *counter = NULL;
- counter = mlx5_flow_rule_counter(flow->rule);
- mlx5_del_flow_rules(flow->rule);
+ counter = mlx5_flow_rule_counter(flow->rule[0]);
+ mlx5_del_flow_rules(flow->rule[0]);
mlx5_fc_destroy(priv->mdev, counter);
if (!mlx5e_tc_num_filters(priv) && priv->fs.tc.t) {
@@ -870,9 +872,18 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
rule = mlx5_eswitch_add_offloaded_rule(esw, &parse_attr->spec, attr);
if (IS_ERR(rule))
goto err_add_rule;
+
+ if (attr->mirror_count) {
+ flow->rule[1] = mlx5_eswitch_add_fwd_rule(esw, &parse_attr->spec, attr);
+ if (IS_ERR(flow->rule[1]))
+ goto err_fwd_rule;
+ }
}
return rule;
+err_fwd_rule:
+ mlx5_eswitch_del_offloaded_rule(esw, rule, attr);
+ rule = flow->rule[1];
err_add_rule:
if (attr->action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR)
mlx5e_detach_mod_hdr(priv, flow);
@@ -893,7 +904,9 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv,
if (flow->flags & MLX5E_TC_FLOW_OFFLOADED) {
flow->flags &= ~MLX5E_TC_FLOW_OFFLOADED;
- mlx5_eswitch_del_offloaded_rule(esw, flow->rule, attr);
+ if (attr->mirror_count)
+ mlx5_eswitch_del_offloaded_rule(esw, flow->rule[1], attr);
+ mlx5_eswitch_del_offloaded_rule(esw, flow->rule[0], attr);
}
mlx5_eswitch_del_vlan_action(esw, attr);
@@ -929,13 +942,25 @@ void mlx5e_tc_encap_flows_add(struct mlx5e_priv *priv,
list_for_each_entry(flow, &e->flows, encap) {
esw_attr = flow->esw_attr;
esw_attr->encap_id = e->encap_id;
- flow->rule = mlx5_eswitch_add_offloaded_rule(esw, &esw_attr->parse_attr->spec, esw_attr);
- if (IS_ERR(flow->rule)) {
- err = PTR_ERR(flow->rule);
+ flow->rule[0] = mlx5_eswitch_add_offloaded_rule(esw, &esw_attr->parse_attr->spec, esw_attr);
+ if (IS_ERR(flow->rule[0])) {
+ err = PTR_ERR(flow->rule[0]);
mlx5_core_warn(priv->mdev, "Failed to update cached encapsulation flow, %d\n",
err);
continue;
}
+
+ if (esw_attr->mirror_count) {
+ flow->rule[1] = mlx5_eswitch_add_fwd_rule(esw, &esw_attr->parse_attr->spec, esw_attr);
+ if (IS_ERR(flow->rule[1])) {
+ mlx5_eswitch_del_offloaded_rule(esw, flow->rule[0], esw_attr);
+ err = PTR_ERR(flow->rule[1]);
+ mlx5_core_warn(priv->mdev, "Failed to update cached mirror flow, %d\n",
+ err);
+ continue;
+ }
+ }
+
flow->flags |= MLX5E_TC_FLOW_OFFLOADED;
}
}
@@ -948,8 +973,12 @@ void mlx5e_tc_encap_flows_del(struct mlx5e_priv *priv,
list_for_each_entry(flow, &e->flows, encap) {
if (flow->flags & MLX5E_TC_FLOW_OFFLOADED) {
+ struct mlx5_esw_flow_attr *attr = flow->esw_attr;
+
flow->flags &= ~MLX5E_TC_FLOW_OFFLOADED;
- mlx5_eswitch_del_offloaded_rule(esw, flow->rule, flow->esw_attr);
+ if (attr->mirror_count)
+ mlx5_eswitch_del_offloaded_rule(esw, flow->rule[1], attr);
+ mlx5_eswitch_del_offloaded_rule(esw, flow->rule[0], attr);
}
}
@@ -984,7 +1013,7 @@ void mlx5e_tc_update_neigh_used_value(struct mlx5e_neigh_hash_entry *nhe)
continue;
list_for_each_entry(flow, &e->flows, encap) {
if (flow->flags & MLX5E_TC_FLOW_OFFLOADED) {
- counter = mlx5_flow_rule_counter(flow->rule);
+ counter = mlx5_flow_rule_counter(flow->rule[0]);
mlx5_fc_query_cached(counter, &bytes, &packets, &lastuse);
if (time_after((unsigned long)lastuse, nhe->reported_lastuse)) {
neigh_used = true;
@@ -2714,16 +2743,16 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv,
err = parse_tc_fdb_actions(priv, f->exts, parse_attr, flow);
if (err < 0)
goto err_free;
- flow->rule = mlx5e_tc_add_fdb_flow(priv, parse_attr, flow);
+ flow->rule[0] = mlx5e_tc_add_fdb_flow(priv, parse_attr, flow);
} else {
err = parse_tc_nic_actions(priv, f->exts, parse_attr, flow);
if (err < 0)
goto err_free;
- flow->rule = mlx5e_tc_add_nic_flow(priv, parse_attr, flow);
+ flow->rule[0] = mlx5e_tc_add_nic_flow(priv, parse_attr, flow);
}
- if (IS_ERR(flow->rule)) {
- err = PTR_ERR(flow->rule);
+ if (IS_ERR(flow->rule[0])) {
+ err = PTR_ERR(flow->rule[0]);
if (err != -EAGAIN)
goto err_free;
}
@@ -2796,7 +2825,7 @@ int mlx5e_stats_flower(struct mlx5e_priv *priv,
if (!(flow->flags & MLX5E_TC_FLOW_OFFLOADED))
return 0;
- counter = mlx5_flow_rule_counter(flow->rule);
+ counter = mlx5_flow_rule_counter(flow->rule[0]);
if (!counter)
return 0;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
index 386b0e354c41..b174da2884c5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
@@ -219,6 +219,10 @@ struct mlx5_flow_handle *
mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
struct mlx5_flow_spec *spec,
struct mlx5_esw_flow_attr *attr);
+struct mlx5_flow_handle *
+mlx5_eswitch_add_fwd_rule(struct mlx5_eswitch *esw,
+ struct mlx5_flow_spec *spec,
+ struct mlx5_esw_flow_attr *attr);
void
mlx5_eswitch_del_offloaded_rule(struct mlx5_eswitch *esw,
struct mlx5_flow_handle *rule,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
index 7db8b9a41925..cecd201f0b73 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
@@ -50,6 +50,7 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
{
struct mlx5_flow_destination dest[MLX5_MAX_FLOW_FWD_VPORTS + 1] = {};
struct mlx5_flow_act flow_act = {0};
+ struct mlx5_flow_table *ft = NULL;
struct mlx5_fc *counter = NULL;
struct mlx5_flow_handle *rule;
int j, i = 0;
@@ -58,6 +59,11 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
if (esw->mode != SRIOV_OFFLOADS)
return ERR_PTR(-EOPNOTSUPP);
+ if (attr->mirror_count)
+ ft = esw->fdb_table.offloads.fwd_fdb;
+ else
+ ft = esw->fdb_table.offloads.fast_fdb;
+
flow_act.action = attr->action;
/* if per flow vlan pop/push is emulated, don't set that into the firmware */
if (!mlx5_eswitch_vlan_actions_supported(esw->dev))
@@ -73,11 +79,9 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
for (j = attr->mirror_count; j < attr->out_count; j++) {
dest[i].type = MLX5_FLOW_DESTINATION_TYPE_VPORT;
dest[i].vport.num = attr->out_rep[j]->vport;
- if (MLX5_CAP_ESW(esw->dev, merged_eswitch)) {
- dest[i].vport.vhca_id =
- MLX5_CAP_GEN(attr->out_mdev[j], vhca_id);
- dest[i].vport.vhca_id_valid = 1;
- }
+ dest[i].vport.vhca_id =
+ MLX5_CAP_GEN(attr->out_mdev[j], vhca_id);
+ dest[i].vport.vhca_id_valid = !!MLX5_CAP_ESW(esw->dev, merged_eswitch);
i++;
}
}
@@ -121,8 +125,7 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_ENCAP)
flow_act.encap_id = attr->encap_id;
- rule = mlx5_add_flow_rules((struct mlx5_flow_table *)esw->fdb_table.offloads.fast_fdb,
- spec, &flow_act, dest, i);
+ rule = mlx5_add_flow_rules(ft, spec, &flow_act, dest, i);
if (IS_ERR(rule))
goto err_add_rule;
else
@@ -136,6 +139,57 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
return rule;
}
+struct mlx5_flow_handle *
+mlx5_eswitch_add_fwd_rule(struct mlx5_eswitch *esw,
+ struct mlx5_flow_spec *spec,
+ struct mlx5_esw_flow_attr *attr)
+{
+ struct mlx5_flow_destination dest[MLX5_MAX_FLOW_FWD_VPORTS + 1] = {};
+ struct mlx5_flow_act flow_act = {0};
+ struct mlx5_flow_handle *rule;
+ void *misc;
+ int i;
+
+ flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
+ for (i = 0; i < attr->mirror_count; i++) {
+ dest[i].type = MLX5_FLOW_DESTINATION_TYPE_VPORT;
+ dest[i].vport.num = attr->out_rep[i]->vport;
+ dest[i].vport.vhca_id =
+ MLX5_CAP_GEN(attr->out_mdev[i], vhca_id);
+ dest[i].vport.vhca_id_valid = !!MLX5_CAP_ESW(esw->dev, merged_eswitch);
+ }
+ dest[i].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
+ dest[i].ft = esw->fdb_table.offloads.fwd_fdb,
+ i++;
+
+ misc = MLX5_ADDR_OF(fte_match_param, spec->match_value, misc_parameters);
+ MLX5_SET(fte_match_set_misc, misc, source_port, attr->in_rep->vport);
+
+ if (MLX5_CAP_ESW(esw->dev, merged_eswitch))
+ MLX5_SET(fte_match_set_misc, misc,
+ source_eswitch_owner_vhca_id,
+ MLX5_CAP_GEN(attr->in_mdev, vhca_id));
+
+ misc = MLX5_ADDR_OF(fte_match_param, spec->match_criteria, misc_parameters);
+ MLX5_SET_TO_ONES(fte_match_set_misc, misc, source_port);
+ if (MLX5_CAP_ESW(esw->dev, merged_eswitch))
+ MLX5_SET_TO_ONES(fte_match_set_misc, misc,
+ source_eswitch_owner_vhca_id);
+
+ if (attr->match_level == MLX5_MATCH_NONE)
+ spec->match_criteria_enable = MLX5_MATCH_MISC_PARAMETERS;
+ else
+ spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS |
+ MLX5_MATCH_MISC_PARAMETERS;
+
+ rule = mlx5_add_flow_rules(esw->fdb_table.offloads.fast_fdb, spec, &flow_act, dest, i);
+
+ if (!IS_ERR(rule))
+ esw->offloads.num_flows++;
+
+ return rule;
+}
+
void
mlx5_eswitch_del_offloaded_rule(struct mlx5_eswitch *esw,
struct mlx5_flow_handle *rule,
--
2.17.0
^ permalink raw reply related
* [for-next 07/12] net/mlx5e: TX, Use actual WQE size for SQ edge fill
From: Saeed Mahameed @ 2018-05-26 0:02 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Tariq Toukan, Saeed Mahameed
In-Reply-To: <20180526000207.19568-1-saeedm@mellanox.com>
From: Tariq Toukan <tariqt@mellanox.com>
We fill SQ edge with NOPs to avoid WQEs wrap.
Here, instead of doing that in advance for the maximum possible
WQE size, we do it on-demand using the actual WQE size.
We re-order some parts in mlx5e_sq_xmit to finish the calculation
of WQE size (ds_cnt) before doing any writes to the WQE buffer.
When SQ work queue is fragmented (introduced in an downstream patch),
dealing with WQE wraps becomes more frequent. This change would drastically
reduce the overhead in this case.
Performance tests:
ConnectX-5 100Gbps, CPU: Intel(R) Xeon(R) CPU E5-2680 v3 @ 2.50GHz
Packet rate of 64B packets, single transmit ring, size 8K.
Before: 14.9 Mpps
After: 15.8 Mpps
Improvement of 6%.
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en.h | 3 +-
.../net/ethernet/mellanox/mlx5/core/en_main.c | 4 -
.../net/ethernet/mellanox/mlx5/core/en_rx.c | 27 ++-
.../net/ethernet/mellanox/mlx5/core/en_tx.c | 213 +++++++++++-------
.../ethernet/mellanox/mlx5/core/ipoib/ipoib.h | 23 ++
5 files changed, 178 insertions(+), 92 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index 061c4e90692e..3c0f0a0343fd 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -183,6 +183,7 @@ static inline int mlx5e_get_max_num_channels(struct mlx5_core_dev *mdev)
struct mlx5e_tx_wqe {
struct mlx5_wqe_ctrl_seg ctrl;
struct mlx5_wqe_eth_seg eth;
+ struct mlx5_wqe_data_seg data[0];
};
struct mlx5e_rx_wqe {
@@ -374,7 +375,6 @@ struct mlx5e_txqsq {
struct netdev_queue *txq;
u32 sqn;
u8 min_inline_mode;
- u16 edge;
struct device *pdev;
__be32 mkey_be;
unsigned long state;
@@ -439,7 +439,6 @@ struct mlx5e_icosq {
struct mlx5_wq_cyc wq;
void __iomem *uar_map;
u32 sqn;
- u16 edge;
unsigned long state;
/* control path */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 41f57afc5140..a8b1e43384ca 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -959,8 +959,6 @@ static int mlx5e_alloc_icosq(struct mlx5e_channel *c,
if (err)
goto err_sq_wq_destroy;
- sq->edge = mlx5_wq_cyc_get_size(wq) - MLX5E_ICOSQ_MAX_WQEBBS;
-
return 0;
err_sq_wq_destroy:
@@ -1039,8 +1037,6 @@ static int mlx5e_alloc_txqsq(struct mlx5e_channel *c,
INIT_WORK(&sq->dim.work, mlx5e_tx_dim_work);
sq->dim.mode = params->tx_cq_moderation.cq_period_mode;
- sq->edge = mlx5_wq_cyc_get_size(wq) - MLX5_SEND_WQE_MAX_WQEBBS;
-
return 0;
err_sq_wq_destroy:
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index 7fd3ec877ba4..f4d2c8886492 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -383,6 +383,22 @@ static inline u16 mlx5e_icosq_wrap_cnt(struct mlx5e_icosq *sq)
return sq->pc >> MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE;
}
+static inline void mlx5e_fill_icosq_edge(struct mlx5e_icosq *sq,
+ struct mlx5_wq_cyc *wq,
+ u16 pi)
+{
+ struct mlx5e_sq_wqe_info *edge_wi, *wi = &sq->db.ico_wqe[pi];
+ u8 nnops = mlx5_wq_cyc_get_size(wq) - pi;
+
+ edge_wi = wi + nnops;
+
+ /* fill sq edge with nops to avoid wqe wrapping two pages */
+ for (; wi < edge_wi; wi++) {
+ wi->opcode = MLX5_OPCODE_NOP;
+ mlx5e_post_nop(wq, sq->sqn, &sq->pc);
+ }
+}
+
static int mlx5e_alloc_rx_mpwqe(struct mlx5e_rq *rq, u16 ix)
{
struct mlx5e_mpw_info *wi = &rq->mpwqe.info[ix];
@@ -391,14 +407,15 @@ static int mlx5e_alloc_rx_mpwqe(struct mlx5e_rq *rq, u16 ix)
struct mlx5_wq_cyc *wq = &sq->wq;
struct mlx5e_umr_wqe *umr_wqe;
u16 xlt_offset = ix << (MLX5E_LOG_ALIGNED_MPWQE_PPW - 1);
- int err;
u16 pi;
+ int err;
int i;
- /* fill sq edge with nops to avoid wqe wrap around */
- while ((pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc)) > sq->edge) {
- sq->db.ico_wqe[pi].opcode = MLX5_OPCODE_NOP;
- mlx5e_post_nop(wq, sq->sqn, &sq->pc);
+ pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc);
+
+ if (unlikely(pi + MLX5E_UMR_WQEBBS > mlx5_wq_cyc_get_size(wq))) {
+ mlx5e_fill_icosq_edge(sq, wq, pi);
+ pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc);
}
umr_wqe = mlx5_wq_cyc_get_wqe(wq, pi);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
index c9864fcf00b9..fc68e72b0b2b 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
@@ -230,13 +230,10 @@ mlx5e_txwqe_build_eseg_csum(struct mlx5e_txqsq *sq, struct sk_buff *skb, struct
}
static inline u16
-mlx5e_txwqe_build_eseg_gso(struct mlx5e_txqsq *sq, struct sk_buff *skb,
- struct mlx5_wqe_eth_seg *eseg, unsigned int *num_bytes)
+mlx5e_tx_get_gso_ihs(struct mlx5e_txqsq *sq, struct sk_buff *skb)
{
u16 ihs;
- eseg->mss = cpu_to_be16(skb_shinfo(skb)->gso_size);
-
if (skb->encapsulation) {
ihs = skb_inner_transport_offset(skb) + inner_tcp_hdrlen(skb);
sq->stats.tso_inner_packets++;
@@ -247,7 +244,6 @@ mlx5e_txwqe_build_eseg_gso(struct mlx5e_txqsq *sq, struct sk_buff *skb,
sq->stats.tso_bytes += skb->len - ihs;
}
- *num_bytes = skb->len + (skb_shinfo(skb)->gso_segs - 1) * ihs;
return ihs;
}
@@ -300,17 +296,34 @@ mlx5e_txwqe_build_dsegs(struct mlx5e_txqsq *sq, struct sk_buff *skb,
return -ENOMEM;
}
+static inline void mlx5e_fill_sq_edge(struct mlx5e_txqsq *sq,
+ struct mlx5_wq_cyc *wq,
+ u16 pi)
+{
+ struct mlx5e_tx_wqe_info *edge_wi, *wi = &sq->db.wqe_info[pi];
+ u8 nnops = mlx5_wq_cyc_get_size(wq) - pi;
+
+ edge_wi = wi + nnops;
+
+ /* fill sq edge with nops to avoid wqe wrap around */
+ for (; wi < edge_wi; wi++) {
+ wi->skb = NULL;
+ wi->num_wqebbs = 1;
+ mlx5e_post_nop(wq, sq->sqn, &sq->pc);
+ }
+ sq->stats.nop += nnops;
+}
+
static inline void
mlx5e_txwqe_complete(struct mlx5e_txqsq *sq, struct sk_buff *skb,
- u8 opcode, u16 ds_cnt, u32 num_bytes, u8 num_dma,
+ u8 opcode, u16 ds_cnt, u8 num_wqebbs, u32 num_bytes, u8 num_dma,
struct mlx5e_tx_wqe_info *wi, struct mlx5_wqe_ctrl_seg *cseg)
{
struct mlx5_wq_cyc *wq = &sq->wq;
- u16 pi;
wi->num_bytes = num_bytes;
wi->num_dma = num_dma;
- wi->num_wqebbs = DIV_ROUND_UP(ds_cnt, MLX5_SEND_WQEBB_NUM_DS);
+ wi->num_wqebbs = num_wqebbs;
wi->skb = skb;
cseg->opmod_idx_opcode = cpu_to_be32((sq->pc << 8) | opcode);
@@ -329,58 +342,85 @@ mlx5e_txwqe_complete(struct mlx5e_txqsq *sq, struct sk_buff *skb,
if (!skb->xmit_more || netif_xmit_stopped(sq->txq))
mlx5e_notify_hw(wq, sq->pc, sq->uar_map, cseg);
-
- /* fill sq edge with nops to avoid wqe wrap around */
- while ((pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc)) > sq->edge) {
- sq->db.wqe_info[pi].skb = NULL;
- mlx5e_post_nop(wq, sq->sqn, &sq->pc);
- sq->stats.nop++;
- }
}
+#define INL_HDR_START_SZ (sizeof(((struct mlx5_wqe_eth_seg *)NULL)->inline_hdr.start))
+
netdev_tx_t mlx5e_sq_xmit(struct mlx5e_txqsq *sq, struct sk_buff *skb,
struct mlx5e_tx_wqe *wqe, u16 pi)
{
- struct mlx5e_tx_wqe_info *wi = &sq->db.wqe_info[pi];
-
- struct mlx5_wqe_ctrl_seg *cseg = &wqe->ctrl;
- struct mlx5_wqe_eth_seg *eseg = &wqe->eth;
+ struct mlx5_wq_cyc *wq = &sq->wq;
+ struct mlx5_wqe_ctrl_seg *cseg;
+ struct mlx5_wqe_eth_seg *eseg;
+ struct mlx5_wqe_data_seg *dseg;
+ struct mlx5e_tx_wqe_info *wi;
unsigned char *skb_data = skb->data;
unsigned int skb_len = skb->len;
- u8 opcode = MLX5_OPCODE_SEND;
- unsigned int num_bytes;
+ u16 ds_cnt, ds_cnt_inl = 0;
+ u8 num_wqebbs, opcode;
+ u16 headlen, ihs;
+ u32 num_bytes;
int num_dma;
- u16 headlen;
- u16 ds_cnt;
- u16 ihs;
-
- mlx5e_txwqe_build_eseg_csum(sq, skb, eseg);
+ __be16 mss;
+ /* Calc ihs and ds cnt, no writes to wqe yet */
+ ds_cnt = sizeof(*wqe) / MLX5_SEND_WQE_DS;
if (skb_is_gso(skb)) {
- opcode = MLX5_OPCODE_LSO;
- ihs = mlx5e_txwqe_build_eseg_gso(sq, skb, eseg, &num_bytes);
+ opcode = MLX5_OPCODE_LSO;
+ mss = cpu_to_be16(skb_shinfo(skb)->gso_size);
+ ihs = mlx5e_tx_get_gso_ihs(sq, skb);
+ num_bytes = skb->len + (skb_shinfo(skb)->gso_segs - 1) * ihs;
sq->stats.packets += skb_shinfo(skb)->gso_segs;
} else {
- ihs = mlx5e_calc_min_inline(sq->min_inline_mode, skb);
+ opcode = MLX5_OPCODE_SEND;
+ mss = 0;
+ ihs = mlx5e_calc_min_inline(sq->min_inline_mode, skb);
num_bytes = max_t(unsigned int, skb->len, ETH_ZLEN);
sq->stats.packets++;
}
- sq->stats.bytes += num_bytes;
+
+ sq->stats.bytes += num_bytes;
sq->stats.xmit_more += skb->xmit_more;
- ds_cnt = sizeof(*wqe) / MLX5_SEND_WQE_DS;
+ headlen = skb_len - ihs - skb->data_len;
+ ds_cnt += !!headlen;
+ ds_cnt += skb_shinfo(skb)->nr_frags;
+
+ if (ihs) {
+ ihs += !!skb_vlan_tag_present(skb) * VLAN_HLEN;
+
+ ds_cnt_inl = DIV_ROUND_UP(ihs - INL_HDR_START_SZ, MLX5_SEND_WQE_DS);
+ ds_cnt += ds_cnt_inl;
+ }
+
+ num_wqebbs = DIV_ROUND_UP(ds_cnt, MLX5_SEND_WQEBB_NUM_DS);
+ if (unlikely(pi + num_wqebbs > mlx5_wq_cyc_get_size(wq))) {
+ mlx5e_fill_sq_edge(sq, wq, pi);
+ mlx5e_sq_fetch_wqe(sq, &wqe, &pi);
+ }
+
+ /* fill wqe */
+ wi = &sq->db.wqe_info[pi];
+ cseg = &wqe->ctrl;
+ eseg = &wqe->eth;
+ dseg = wqe->data;
+
+ mlx5e_txwqe_build_eseg_csum(sq, skb, eseg);
+
+ eseg->mss = mss;
+
if (ihs) {
if (skb_vlan_tag_present(skb)) {
- mlx5e_insert_vlan(eseg->inline_hdr.start, skb, ihs, &skb_data, &skb_len);
- ihs += VLAN_HLEN;
+ mlx5e_insert_vlan(eseg->inline_hdr.start, skb,
+ ihs - VLAN_HLEN, &skb_data, &skb_len);
sq->stats.added_vlan_packets++;
} else {
memcpy(eseg->inline_hdr.start, skb_data, ihs);
mlx5e_tx_skb_pull_inline(&skb_data, &skb_len, ihs);
}
eseg->inline_hdr.sz = cpu_to_be16(ihs);
- ds_cnt += DIV_ROUND_UP(ihs - sizeof(eseg->inline_hdr.start), MLX5_SEND_WQE_DS);
+ dseg += ds_cnt_inl;
} else if (skb_vlan_tag_present(skb)) {
eseg->insert.type = cpu_to_be16(MLX5_ETH_WQE_INSERT_VLAN);
if (skb->vlan_proto == cpu_to_be16(ETH_P_8021AD))
@@ -389,14 +429,12 @@ netdev_tx_t mlx5e_sq_xmit(struct mlx5e_txqsq *sq, struct sk_buff *skb,
sq->stats.added_vlan_packets++;
}
- headlen = skb_len - skb->data_len;
- num_dma = mlx5e_txwqe_build_dsegs(sq, skb, skb_data, headlen,
- (struct mlx5_wqe_data_seg *)cseg + ds_cnt);
+ num_dma = mlx5e_txwqe_build_dsegs(sq, skb, skb_data, headlen, dseg);
if (unlikely(num_dma < 0))
goto err_drop;
- mlx5e_txwqe_complete(sq, skb, opcode, ds_cnt + num_dma,
- num_bytes, num_dma, wi, cseg);
+ mlx5e_txwqe_complete(sq, skb, opcode, ds_cnt, num_wqebbs, num_bytes,
+ num_dma, wi, cseg);
return NETDEV_TX_OK;
@@ -581,18 +619,6 @@ void mlx5e_free_txqsq_descs(struct mlx5e_txqsq *sq)
}
#ifdef CONFIG_MLX5_CORE_IPOIB
-
-struct mlx5_wqe_eth_pad {
- u8 rsvd0[16];
-};
-
-struct mlx5i_tx_wqe {
- struct mlx5_wqe_ctrl_seg ctrl;
- struct mlx5_wqe_datagram_seg datagram;
- struct mlx5_wqe_eth_pad pad;
- struct mlx5_wqe_eth_seg eth;
-};
-
static inline void
mlx5i_txwqe_build_datagram(struct mlx5_av *av, u32 dqpn, u32 dqkey,
struct mlx5_wqe_datagram_seg *dseg)
@@ -605,59 +631,85 @@ mlx5i_txwqe_build_datagram(struct mlx5_av *av, u32 dqpn, u32 dqkey,
netdev_tx_t mlx5i_sq_xmit(struct mlx5e_txqsq *sq, struct sk_buff *skb,
struct mlx5_av *av, u32 dqpn, u32 dqkey)
{
- struct mlx5_wq_cyc *wq = &sq->wq;
- u16 pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc);
- struct mlx5i_tx_wqe *wqe = mlx5_wq_cyc_get_wqe(wq, pi);
- struct mlx5e_tx_wqe_info *wi = &sq->db.wqe_info[pi];
+ struct mlx5_wq_cyc *wq = &sq->wq;
+ struct mlx5i_tx_wqe *wqe;
- struct mlx5_wqe_ctrl_seg *cseg = &wqe->ctrl;
- struct mlx5_wqe_datagram_seg *datagram = &wqe->datagram;
- struct mlx5_wqe_eth_seg *eseg = &wqe->eth;
+ struct mlx5_wqe_datagram_seg *datagram;
+ struct mlx5_wqe_ctrl_seg *cseg;
+ struct mlx5_wqe_eth_seg *eseg;
+ struct mlx5_wqe_data_seg *dseg;
+ struct mlx5e_tx_wqe_info *wi;
unsigned char *skb_data = skb->data;
unsigned int skb_len = skb->len;
- u8 opcode = MLX5_OPCODE_SEND;
- unsigned int num_bytes;
+ u16 ds_cnt, ds_cnt_inl = 0;
+ u8 num_wqebbs, opcode;
+ u16 headlen, ihs, pi;
+ u32 num_bytes;
int num_dma;
- u16 headlen;
- u16 ds_cnt;
- u16 ihs;
-
- memset(wqe, 0, sizeof(*wqe));
+ __be16 mss;
- mlx5i_txwqe_build_datagram(av, dqpn, dqkey, datagram);
-
- mlx5e_txwqe_build_eseg_csum(sq, skb, eseg);
+ mlx5i_sq_fetch_wqe(sq, &wqe, &pi);
+ /* Calc ihs and ds cnt, no writes to wqe yet */
+ ds_cnt = sizeof(*wqe) / MLX5_SEND_WQE_DS;
if (skb_is_gso(skb)) {
- opcode = MLX5_OPCODE_LSO;
- ihs = mlx5e_txwqe_build_eseg_gso(sq, skb, eseg, &num_bytes);
+ opcode = MLX5_OPCODE_LSO;
+ mss = cpu_to_be16(skb_shinfo(skb)->gso_size);
+ ihs = mlx5e_tx_get_gso_ihs(sq, skb);
+ num_bytes = skb->len + (skb_shinfo(skb)->gso_segs - 1) * ihs;
sq->stats.packets += skb_shinfo(skb)->gso_segs;
} else {
- ihs = mlx5e_calc_min_inline(sq->min_inline_mode, skb);
+ opcode = MLX5_OPCODE_SEND;
+ mss = 0;
+ ihs = mlx5e_calc_min_inline(sq->min_inline_mode, skb);
num_bytes = max_t(unsigned int, skb->len, ETH_ZLEN);
sq->stats.packets++;
}
- sq->stats.bytes += num_bytes;
+ sq->stats.bytes += num_bytes;
sq->stats.xmit_more += skb->xmit_more;
- ds_cnt = sizeof(*wqe) / MLX5_SEND_WQE_DS;
+ headlen = skb_len - ihs - skb->data_len;
+ ds_cnt += !!headlen;
+ ds_cnt += skb_shinfo(skb)->nr_frags;
+
+ if (ihs) {
+ ds_cnt_inl = DIV_ROUND_UP(ihs - INL_HDR_START_SZ, MLX5_SEND_WQE_DS);
+ ds_cnt += ds_cnt_inl;
+ }
+
+ num_wqebbs = DIV_ROUND_UP(ds_cnt, MLX5_SEND_WQEBB_NUM_DS);
+ if (unlikely(pi + num_wqebbs > mlx5_wq_cyc_get_size(wq))) {
+ mlx5e_fill_sq_edge(sq, wq, pi);
+ mlx5i_sq_fetch_wqe(sq, &wqe, &pi);
+ }
+
+ /* fill wqe */
+ wi = &sq->db.wqe_info[pi];
+ cseg = &wqe->ctrl;
+ datagram = &wqe->datagram;
+ eseg = &wqe->eth;
+ dseg = wqe->data;
+
+ mlx5i_txwqe_build_datagram(av, dqpn, dqkey, datagram);
+
+ mlx5e_txwqe_build_eseg_csum(sq, skb, eseg);
+
+ eseg->mss = mss;
+
if (ihs) {
memcpy(eseg->inline_hdr.start, skb_data, ihs);
- mlx5e_tx_skb_pull_inline(&skb_data, &skb_len, ihs);
eseg->inline_hdr.sz = cpu_to_be16(ihs);
- ds_cnt += DIV_ROUND_UP(ihs - sizeof(eseg->inline_hdr.start), MLX5_SEND_WQE_DS);
+ dseg += ds_cnt_inl;
}
- headlen = skb_len - skb->data_len;
- num_dma = mlx5e_txwqe_build_dsegs(sq, skb, skb_data, headlen,
- (struct mlx5_wqe_data_seg *)cseg + ds_cnt);
+ num_dma = mlx5e_txwqe_build_dsegs(sq, skb, skb_data, headlen, dseg);
if (unlikely(num_dma < 0))
goto err_drop;
- mlx5e_txwqe_complete(sq, skb, opcode, ds_cnt + num_dma,
- num_bytes, num_dma, wi, cseg);
+ mlx5e_txwqe_complete(sq, skb, opcode, ds_cnt, num_wqebbs, num_bytes,
+ num_dma, wi, cseg);
return NETDEV_TX_OK;
@@ -667,5 +719,4 @@ netdev_tx_t mlx5i_sq_xmit(struct mlx5e_txqsq *sq, struct sk_buff *skb,
return NETDEV_TX_OK;
}
-
#endif
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.h b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.h
index 6d9053bcbe95..45a11864e544 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.h
@@ -93,6 +93,29 @@ const struct mlx5e_profile *mlx5i_pkey_get_profile(void);
/* Extract mlx5e_priv from IPoIB netdev */
#define mlx5i_epriv(netdev) ((void *)(((struct mlx5i_priv *)netdev_priv(netdev))->mlx5e_priv))
+struct mlx5_wqe_eth_pad {
+ u8 rsvd0[16];
+};
+
+struct mlx5i_tx_wqe {
+ struct mlx5_wqe_ctrl_seg ctrl;
+ struct mlx5_wqe_datagram_seg datagram;
+ struct mlx5_wqe_eth_pad pad;
+ struct mlx5_wqe_eth_seg eth;
+ struct mlx5_wqe_data_seg data[0];
+};
+
+static inline void mlx5i_sq_fetch_wqe(struct mlx5e_txqsq *sq,
+ struct mlx5i_tx_wqe **wqe,
+ u16 *pi)
+{
+ struct mlx5_wq_cyc *wq = &sq->wq;
+
+ *pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc);
+ *wqe = mlx5_wq_cyc_get_wqe(wq, *pi);
+ memset(*wqe, 0, sizeof(**wqe));
+}
+
netdev_tx_t mlx5i_sq_xmit(struct mlx5e_txqsq *sq, struct sk_buff *skb,
struct mlx5_av *av, u32 dqpn, u32 dqkey);
void mlx5i_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe);
--
2.17.0
^ permalink raw reply related
* [for-next 06/12] net/mlx5e: Use WQ API functions instead of direct fields access
From: Saeed Mahameed @ 2018-05-26 0:02 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Tariq Toukan, Saeed Mahameed
In-Reply-To: <20180526000207.19568-1-saeedm@mellanox.com>
From: Tariq Toukan <tariqt@mellanox.com>
Use the WQ API to get the WQ size, and to map a counter
into a WQ entry index.
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en.h | 9 ++---
.../net/ethernet/mellanox/mlx5/core/en_main.c | 37 +++++++++++--------
.../net/ethernet/mellanox/mlx5/core/en_rx.c | 25 +++++++------
.../net/ethernet/mellanox/mlx5/core/en_tx.c | 8 ++--
drivers/net/ethernet/mellanox/mlx5/core/wq.h | 19 +++++++++-
5 files changed, 60 insertions(+), 38 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index c5c7a6d687ff..061c4e90692e 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -450,7 +450,7 @@ struct mlx5e_icosq {
static inline bool
mlx5e_wqc_has_room_for(struct mlx5_wq_cyc *wq, u16 cc, u16 pc, u16 n)
{
- return (((wq->sz_m1 & (cc - pc)) >= n) || (cc == pc));
+ return (mlx5_wq_cyc_ctr2ix(wq, cc - pc) >= n) || (cc == pc);
}
struct mlx5e_dma_info {
@@ -956,10 +956,9 @@ static inline void mlx5e_sq_fetch_wqe(struct mlx5e_txqsq *sq,
struct mlx5e_tx_wqe **wqe,
u16 *pi)
{
- struct mlx5_wq_cyc *wq;
+ struct mlx5_wq_cyc *wq = &sq->wq;
- wq = &sq->wq;
- *pi = sq->pc & wq->sz_m1;
+ *pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc);
*wqe = mlx5_wq_cyc_get_wqe(wq, *pi);
memset(*wqe, 0, sizeof(**wqe));
}
@@ -967,7 +966,7 @@ static inline void mlx5e_sq_fetch_wqe(struct mlx5e_txqsq *sq,
static inline
struct mlx5e_tx_wqe *mlx5e_post_nop(struct mlx5_wq_cyc *wq, u32 sqn, u16 *pc)
{
- u16 pi = *pc & wq->sz_m1;
+ u16 pi = mlx5_wq_cyc_ctr2ix(wq, *pc);
struct mlx5e_tx_wqe *wqe = mlx5_wq_cyc_get_wqe(wq, pi);
struct mlx5_wqe_ctrl_seg *cseg = &wqe->ctrl;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index cee44c21766c..41f57afc5140 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -836,13 +836,15 @@ static int mlx5e_open_rq(struct mlx5e_channel *c,
static void mlx5e_activate_rq(struct mlx5e_rq *rq)
{
struct mlx5e_icosq *sq = &rq->channel->icosq;
- u16 pi = sq->pc & sq->wq.sz_m1;
+ struct mlx5_wq_cyc *wq = &sq->wq;
struct mlx5e_tx_wqe *nopwqe;
+ u16 pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc);
+
set_bit(MLX5E_RQ_STATE_ENABLED, &rq->state);
sq->db.ico_wqe[pi].opcode = MLX5_OPCODE_NOP;
- nopwqe = mlx5e_post_nop(&sq->wq, sq->sqn, &sq->pc);
- mlx5e_notify_hw(&sq->wq, sq->pc, sq->uar_map, &nopwqe->ctrl);
+ nopwqe = mlx5e_post_nop(wq, sq->sqn, &sq->pc);
+ mlx5e_notify_hw(wq, sq->pc, sq->uar_map, &nopwqe->ctrl);
}
static void mlx5e_deactivate_rq(struct mlx5e_rq *rq)
@@ -885,6 +887,7 @@ static int mlx5e_alloc_xdpsq(struct mlx5e_channel *c,
{
void *sqc_wq = MLX5_ADDR_OF(sqc, param->sqc, wq);
struct mlx5_core_dev *mdev = c->mdev;
+ struct mlx5_wq_cyc *wq = &sq->wq;
int err;
sq->pdev = c->pdev;
@@ -894,10 +897,10 @@ static int mlx5e_alloc_xdpsq(struct mlx5e_channel *c,
sq->min_inline_mode = params->tx_min_inline_mode;
param->wq.db_numa_node = cpu_to_node(c->cpu);
- err = mlx5_wq_cyc_create(mdev, ¶m->wq, sqc_wq, &sq->wq, &sq->wq_ctrl);
+ err = mlx5_wq_cyc_create(mdev, ¶m->wq, sqc_wq, wq, &sq->wq_ctrl);
if (err)
return err;
- sq->wq.db = &sq->wq.db[MLX5_SND_DBR];
+ wq->db = &wq->db[MLX5_SND_DBR];
err = mlx5e_alloc_xdpsq_db(sq, cpu_to_node(c->cpu));
if (err)
@@ -940,22 +943,23 @@ static int mlx5e_alloc_icosq(struct mlx5e_channel *c,
{
void *sqc_wq = MLX5_ADDR_OF(sqc, param->sqc, wq);
struct mlx5_core_dev *mdev = c->mdev;
+ struct mlx5_wq_cyc *wq = &sq->wq;
int err;
sq->channel = c;
sq->uar_map = mdev->mlx5e_res.bfreg.map;
param->wq.db_numa_node = cpu_to_node(c->cpu);
- err = mlx5_wq_cyc_create(mdev, ¶m->wq, sqc_wq, &sq->wq, &sq->wq_ctrl);
+ err = mlx5_wq_cyc_create(mdev, ¶m->wq, sqc_wq, wq, &sq->wq_ctrl);
if (err)
return err;
- sq->wq.db = &sq->wq.db[MLX5_SND_DBR];
+ wq->db = &wq->db[MLX5_SND_DBR];
err = mlx5e_alloc_icosq_db(sq, cpu_to_node(c->cpu));
if (err)
goto err_sq_wq_destroy;
- sq->edge = (sq->wq.sz_m1 + 1) - MLX5E_ICOSQ_MAX_WQEBBS;
+ sq->edge = mlx5_wq_cyc_get_size(wq) - MLX5E_ICOSQ_MAX_WQEBBS;
return 0;
@@ -1005,6 +1009,7 @@ static int mlx5e_alloc_txqsq(struct mlx5e_channel *c,
{
void *sqc_wq = MLX5_ADDR_OF(sqc, param->sqc, wq);
struct mlx5_core_dev *mdev = c->mdev;
+ struct mlx5_wq_cyc *wq = &sq->wq;
int err;
sq->pdev = c->pdev;
@@ -1022,10 +1027,10 @@ static int mlx5e_alloc_txqsq(struct mlx5e_channel *c,
set_bit(MLX5E_SQ_STATE_TLS, &sq->state);
param->wq.db_numa_node = cpu_to_node(c->cpu);
- err = mlx5_wq_cyc_create(mdev, ¶m->wq, sqc_wq, &sq->wq, &sq->wq_ctrl);
+ err = mlx5_wq_cyc_create(mdev, ¶m->wq, sqc_wq, wq, &sq->wq_ctrl);
if (err)
return err;
- sq->wq.db = &sq->wq.db[MLX5_SND_DBR];
+ wq->db = &wq->db[MLX5_SND_DBR];
err = mlx5e_alloc_txqsq_db(sq, cpu_to_node(c->cpu));
if (err)
@@ -1034,7 +1039,7 @@ static int mlx5e_alloc_txqsq(struct mlx5e_channel *c,
INIT_WORK(&sq->dim.work, mlx5e_tx_dim_work);
sq->dim.mode = params->tx_cq_moderation.cq_period_mode;
- sq->edge = (sq->wq.sz_m1 + 1) - MLX5_SEND_WQE_MAX_WQEBBS;
+ sq->edge = mlx5_wq_cyc_get_size(wq) - MLX5_SEND_WQE_MAX_WQEBBS;
return 0;
@@ -1238,6 +1243,7 @@ static inline void netif_tx_disable_queue(struct netdev_queue *txq)
static void mlx5e_deactivate_txqsq(struct mlx5e_txqsq *sq)
{
struct mlx5e_channel *c = sq->channel;
+ struct mlx5_wq_cyc *wq = &sq->wq;
clear_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
/* prevent netif_tx_wake_queue */
@@ -1246,12 +1252,13 @@ static void mlx5e_deactivate_txqsq(struct mlx5e_txqsq *sq)
netif_tx_disable_queue(sq->txq);
/* last doorbell out, godspeed .. */
- if (mlx5e_wqc_has_room_for(&sq->wq, sq->cc, sq->pc, 1)) {
+ if (mlx5e_wqc_has_room_for(wq, sq->cc, sq->pc, 1)) {
+ u16 pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc);
struct mlx5e_tx_wqe *nop;
- sq->db.wqe_info[(sq->pc & sq->wq.sz_m1)].skb = NULL;
- nop = mlx5e_post_nop(&sq->wq, sq->sqn, &sq->pc);
- mlx5e_notify_hw(&sq->wq, sq->pc, sq->uar_map, &nop->ctrl);
+ sq->db.wqe_info[pi].skb = NULL;
+ nop = mlx5e_post_nop(wq, sq->sqn, &sq->pc);
+ mlx5e_notify_hw(wq, sq->pc, sq->uar_map, &nop->ctrl);
}
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index 53f72923b164..7fd3ec877ba4 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -54,7 +54,7 @@ static inline bool mlx5e_rx_hw_stamp(struct hwtstamp_config *config)
static inline void mlx5e_read_cqe_slot(struct mlx5e_cq *cq, u32 cqcc,
void *data)
{
- u32 ci = cqcc & cq->wq.fbc.sz_m1;
+ u32 ci = mlx5_cqwq_ctr2ix(&cq->wq, cqcc);
memcpy(data, mlx5_cqwq_get_wqe(&cq->wq, ci), sizeof(struct mlx5_cqe64));
}
@@ -76,10 +76,11 @@ static inline void mlx5e_read_mini_arr_slot(struct mlx5e_cq *cq, u32 cqcc)
static inline void mlx5e_cqes_update_owner(struct mlx5e_cq *cq, u32 cqcc, int n)
{
- struct mlx5_frag_buf_ctrl *fbc = &cq->wq.fbc;
- u8 op_own = (cqcc >> fbc->log_sz) & 1;
- u32 wq_sz = 1 << fbc->log_sz;
- u32 ci = cqcc & fbc->sz_m1;
+ struct mlx5_cqwq *wq = &cq->wq;
+
+ u8 op_own = mlx5_cqwq_get_ctr_wrap_cnt(wq, cqcc) & 1;
+ u32 ci = mlx5_cqwq_ctr2ix(wq, cqcc);
+ u32 wq_sz = mlx5_cqwq_get_size(wq);
u32 ci_top = min_t(u32, wq_sz, ci + n);
for (; ci < ci_top; ci++, n--) {
@@ -112,7 +113,7 @@ static inline void mlx5e_decompress_cqe(struct mlx5e_rq *rq,
mpwrq_get_cqe_consumed_strides(&cq->title);
else
cq->decmprs_wqe_counter =
- (cq->decmprs_wqe_counter + 1) & rq->wq.sz_m1;
+ mlx5_wq_ll_ctr2ix(&rq->wq, cq->decmprs_wqe_counter + 1);
}
static inline void mlx5e_decompress_cqe_no_hash(struct mlx5e_rq *rq,
@@ -395,7 +396,7 @@ static int mlx5e_alloc_rx_mpwqe(struct mlx5e_rq *rq, u16 ix)
int i;
/* fill sq edge with nops to avoid wqe wrap around */
- while ((pi = (sq->pc & wq->sz_m1)) > sq->edge) {
+ while ((pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc)) > sq->edge) {
sq->db.ico_wqe[pi].opcode = MLX5_OPCODE_NOP;
mlx5e_post_nop(wq, sq->sqn, &sq->pc);
}
@@ -482,7 +483,7 @@ static inline void mlx5e_poll_ico_single_cqe(struct mlx5e_cq *cq,
struct mlx5_cqe64 *cqe)
{
struct mlx5_wq_cyc *wq = &sq->wq;
- u16 ci = be16_to_cpu(cqe->wqe_counter) & wq->sz_m1;
+ u16 ci = mlx5_wq_cyc_ctr2ix(wq, be16_to_cpu(cqe->wqe_counter));
struct mlx5e_sq_wqe_info *icowi = &sq->db.ico_wqe[ci];
mlx5_cqwq_pop(&cq->wq);
@@ -731,7 +732,7 @@ static inline void mlx5e_xmit_xdp_doorbell(struct mlx5e_xdpsq *sq)
{
struct mlx5_wq_cyc *wq = &sq->wq;
struct mlx5e_tx_wqe *wqe;
- u16 pi = (sq->pc - 1) & wq->sz_m1; /* last pi */
+ u16 pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc - 1); /* last pi */
wqe = mlx5_wq_cyc_get_wqe(wq, pi);
@@ -744,7 +745,7 @@ static inline bool mlx5e_xmit_xdp_frame(struct mlx5e_rq *rq,
{
struct mlx5e_xdpsq *sq = &rq->xdpsq;
struct mlx5_wq_cyc *wq = &sq->wq;
- u16 pi = sq->pc & wq->sz_m1;
+ u16 pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc);
struct mlx5e_tx_wqe *wqe = mlx5_wq_cyc_get_wqe(wq, pi);
struct mlx5_wqe_ctrl_seg *cseg = &wqe->ctrl;
@@ -1214,7 +1215,7 @@ bool mlx5e_poll_xdpsq_cq(struct mlx5e_cq *cq)
last_wqe = (sqcc == wqe_counter);
- ci = sqcc & sq->wq.sz_m1;
+ ci = mlx5_wq_cyc_ctr2ix(&sq->wq, sqcc);
di = &sq->db.di[ci];
sqcc++;
@@ -1239,7 +1240,7 @@ void mlx5e_free_xdpsq_descs(struct mlx5e_xdpsq *sq)
u16 ci;
while (sq->cc != sq->pc) {
- ci = sq->cc & sq->wq.sz_m1;
+ ci = mlx5_wq_cyc_ctr2ix(&sq->wq, sq->cc);
di = &sq->db.di[ci];
sq->cc++;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
index 2d3f17da5f5c..c9864fcf00b9 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
@@ -331,7 +331,7 @@ mlx5e_txwqe_complete(struct mlx5e_txqsq *sq, struct sk_buff *skb,
mlx5e_notify_hw(wq, sq->pc, sq->uar_map, cseg);
/* fill sq edge with nops to avoid wqe wrap around */
- while ((pi = (sq->pc & wq->sz_m1)) > sq->edge) {
+ while ((pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc)) > sq->edge) {
sq->db.wqe_info[pi].skb = NULL;
mlx5e_post_nop(wq, sq->sqn, &sq->pc);
sq->stats.nop++;
@@ -496,7 +496,7 @@ bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget)
last_wqe = (sqcc == wqe_counter);
- ci = sqcc & sq->wq.sz_m1;
+ ci = mlx5_wq_cyc_ctr2ix(&sq->wq, sqcc);
wi = &sq->db.wqe_info[ci];
skb = wi->skb;
@@ -559,7 +559,7 @@ void mlx5e_free_txqsq_descs(struct mlx5e_txqsq *sq)
int i;
while (sq->cc != sq->pc) {
- ci = sq->cc & sq->wq.sz_m1;
+ ci = mlx5_wq_cyc_ctr2ix(&sq->wq, sq->cc);
wi = &sq->db.wqe_info[ci];
skb = wi->skb;
@@ -606,7 +606,7 @@ netdev_tx_t mlx5i_sq_xmit(struct mlx5e_txqsq *sq, struct sk_buff *skb,
struct mlx5_av *av, u32 dqpn, u32 dqkey)
{
struct mlx5_wq_cyc *wq = &sq->wq;
- u16 pi = sq->pc & wq->sz_m1;
+ u16 pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc);
struct mlx5i_tx_wqe *wqe = mlx5_wq_cyc_get_wqe(wq, pi);
struct mlx5e_tx_wqe_info *wi = &sq->db.wqe_info[pi];
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/wq.h b/drivers/net/ethernet/mellanox/mlx5/core/wq.h
index f3dfa0ca3c5d..a3572e148f09 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/wq.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/wq.h
@@ -123,9 +123,14 @@ static inline int mlx5_wq_cyc_cc_bigger(u16 cc1, u16 cc2)
return !equal && !smaller;
}
+static inline u32 mlx5_cqwq_ctr2ix(struct mlx5_cqwq *wq, u32 ctr)
+{
+ return ctr & wq->fbc.sz_m1;
+}
+
static inline u32 mlx5_cqwq_get_ci(struct mlx5_cqwq *wq)
{
- return wq->cc & wq->fbc.sz_m1;
+ return mlx5_cqwq_ctr2ix(wq, wq->cc);
}
static inline void *mlx5_cqwq_get_wqe(struct mlx5_cqwq *wq, u32 ix)
@@ -133,9 +138,14 @@ static inline void *mlx5_cqwq_get_wqe(struct mlx5_cqwq *wq, u32 ix)
return mlx5_frag_buf_get_wqe(&wq->fbc, ix);
}
+static inline u32 mlx5_cqwq_get_ctr_wrap_cnt(struct mlx5_cqwq *wq, u32 ctr)
+{
+ return ctr >> wq->fbc.log_sz;
+}
+
static inline u32 mlx5_cqwq_get_wrap_cnt(struct mlx5_cqwq *wq)
{
- return wq->cc >> wq->fbc.log_sz;
+ return mlx5_cqwq_get_ctr_wrap_cnt(wq, wq->cc);
}
static inline void mlx5_cqwq_pop(struct mlx5_cqwq *wq)
@@ -174,6 +184,11 @@ static inline int mlx5_wq_ll_is_empty(struct mlx5_wq_ll *wq)
return !wq->cur_sz;
}
+static inline u16 mlx5_wq_ll_ctr2ix(struct mlx5_wq_ll *wq, u16 ctr)
+{
+ return ctr & wq->sz_m1;
+}
+
static inline void *mlx5_wq_ll_get_wqe(struct mlx5_wq_ll *wq, u16 ix)
{
return wq->buf + (ix << wq->log_stride);
--
2.17.0
^ permalink raw reply related
* [for-next 08/12] net/mlx5i: Use compilation flag in IPOIB header
From: Saeed Mahameed @ 2018-05-26 0:02 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Tariq Toukan, Saeed Mahameed
In-Reply-To: <20180526000207.19568-1-saeedm@mellanox.com>
From: Tariq Toukan <tariqt@mellanox.com>
If CONFIG_MLX5_CORE_IPOIB is not set, compile-out the
IPOIB related headers.
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.h b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.h
index 45a11864e544..08eac92fc26c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.h
@@ -33,6 +33,8 @@
#ifndef __MLX5E_IPOB_H__
#define __MLX5E_IPOB_H__
+#ifdef CONFIG_MLX5_CORE_IPOIB
+
#include <linux/mlx5/fs.h>
#include "en.h"
@@ -120,4 +122,5 @@ netdev_tx_t mlx5i_sq_xmit(struct mlx5e_txqsq *sq, struct sk_buff *skb,
struct mlx5_av *av, u32 dqpn, u32 dqkey);
void mlx5i_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe);
+#endif /* CONFIG_MLX5_CORE_IPOIB */
#endif /* __MLX5E_IPOB_H__ */
--
2.17.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox