* Re: [PATCH] net/wan/fsl_ucc_hdlc: error counters
From: David Miller @ 2018-10-23 2:58 UTC (permalink / raw)
To: mathias.thore
Cc: qiang.zhao, linuxppc-dev, netdev, joakim.tjernlund,
david.gounaris
In-Reply-To: <20181022125550.31170-1-mathias.thore@infinera.com>
From: Mathias Thore <mathias.thore@infinera.com>
Date: Mon, 22 Oct 2018 14:55:50 +0200
> Extract error information from rx and tx buffer descriptors,
> and update error counters.
>
> Signed-off-by: Mathias Thore <mathias.thore@infinera.com>
Applied.
^ permalink raw reply
* Re: [PATCH net-next] llc: do not use sk_eat_skb()
From: David Miller @ 2018-10-23 2:59 UTC (permalink / raw)
To: edumazet; +Cc: netdev, eric.dumazet
In-Reply-To: <20181022162427.67169-1-edumazet@google.com>
From: Eric Dumazet <edumazet@google.com>
Date: Mon, 22 Oct 2018 09:24:27 -0700
> syzkaller triggered a use-after-free [1], caused by a combination of
> skb_get() in llc_conn_state_process() and usage of sk_eat_skb()
>
> sk_eat_skb() is assuming the skb about to be freed is only used by
> the current thread. TCP/DCCP stacks enforce this because current
> thread holds the socket lock.
>
> llc_conn_state_process() wants to make sure skb does not disappear,
> and holds a reference on the skb it manipulates. But as soon as this
> skb is added to socket receive queue, another thread can consume it.
>
> This means that llc must use regular skb_unlink() and kfree_skb()
> so that both producer and consumer can safely work on the same skb.
>
> [1]
> BUG: KASAN: use-after-free in atomic_read include/asm-generic/atomic-instrumented.h:21 [inline]
> BUG: KASAN: use-after-free in refcount_read include/linux/refcount.h:43 [inline]
> BUG: KASAN: use-after-free in skb_unref include/linux/skbuff.h:967 [inline]
> BUG: KASAN: use-after-free in kfree_skb+0xb7/0x580 net/core/skbuff.c:655
> Read of size 4 at addr ffff8801d1f6fba4 by task ksoftirqd/1/18
>
> CPU: 1 PID: 18 Comm: ksoftirqd/1 Not tainted 4.19.0-rc8+ #295
> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
> Call Trace:
> __dump_stack lib/dump_stack.c:77 [inline]
> dump_stack+0x1c4/0x2b6 lib/dump_stack.c:113
> print_address_description.cold.8+0x9/0x1ff mm/kasan/report.c:256
> kasan_report_error mm/kasan/report.c:354 [inline]
> kasan_report.cold.9+0x242/0x309 mm/kasan/report.c:412
> check_memory_region_inline mm/kasan/kasan.c:260 [inline]
> check_memory_region+0x13e/0x1b0 mm/kasan/kasan.c:267
> kasan_check_read+0x11/0x20 mm/kasan/kasan.c:272
> atomic_read include/asm-generic/atomic-instrumented.h:21 [inline]
> refcount_read include/linux/refcount.h:43 [inline]
> skb_unref include/linux/skbuff.h:967 [inline]
> kfree_skb+0xb7/0x580 net/core/skbuff.c:655
> llc_sap_state_process+0x9b/0x550 net/llc/llc_sap.c:224
> llc_sap_rcv+0x156/0x1f0 net/llc/llc_sap.c:297
> llc_sap_handler+0x65e/0xf80 net/llc/llc_sap.c:438
> llc_rcv+0x79e/0xe20 net/llc/llc_input.c:208
> __netif_receive_skb_one_core+0x14d/0x200 net/core/dev.c:4913
> __netif_receive_skb+0x2c/0x1e0 net/core/dev.c:5023
> process_backlog+0x218/0x6f0 net/core/dev.c:5829
> napi_poll net/core/dev.c:6249 [inline]
> net_rx_action+0x7c5/0x1950 net/core/dev.c:6315
> __do_softirq+0x30c/0xb03 kernel/softirq.c:292
> run_ksoftirqd+0x94/0x100 kernel/softirq.c:653
> smpboot_thread_fn+0x68b/0xa00 kernel/smpboot.c:164
> kthread+0x35a/0x420 kernel/kthread.c:246
> ret_from_fork+0x3a/0x50 arch/x86/entry/entry_64.S:413
>
> Allocated by task 18:
> save_stack+0x43/0xd0 mm/kasan/kasan.c:448
> set_track mm/kasan/kasan.c:460 [inline]
> kasan_kmalloc+0xc7/0xe0 mm/kasan/kasan.c:553
> kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:490
> kmem_cache_alloc_node+0x144/0x730 mm/slab.c:3644
> __alloc_skb+0x119/0x770 net/core/skbuff.c:193
> alloc_skb include/linux/skbuff.h:995 [inline]
> llc_alloc_frame+0xbc/0x370 net/llc/llc_sap.c:54
> llc_station_ac_send_xid_r net/llc/llc_station.c:52 [inline]
> llc_station_rcv+0x1dc/0x1420 net/llc/llc_station.c:111
> llc_rcv+0xc32/0xe20 net/llc/llc_input.c:220
> __netif_receive_skb_one_core+0x14d/0x200 net/core/dev.c:4913
> __netif_receive_skb+0x2c/0x1e0 net/core/dev.c:5023
> process_backlog+0x218/0x6f0 net/core/dev.c:5829
> napi_poll net/core/dev.c:6249 [inline]
> net_rx_action+0x7c5/0x1950 net/core/dev.c:6315
> __do_softirq+0x30c/0xb03 kernel/softirq.c:292
>
> Freed by task 16383:
> save_stack+0x43/0xd0 mm/kasan/kasan.c:448
> set_track mm/kasan/kasan.c:460 [inline]
> __kasan_slab_free+0x102/0x150 mm/kasan/kasan.c:521
> kasan_slab_free+0xe/0x10 mm/kasan/kasan.c:528
> __cache_free mm/slab.c:3498 [inline]
> kmem_cache_free+0x83/0x290 mm/slab.c:3756
> kfree_skbmem+0x154/0x230 net/core/skbuff.c:582
> __kfree_skb+0x1d/0x20 net/core/skbuff.c:642
> sk_eat_skb include/net/sock.h:2366 [inline]
> llc_ui_recvmsg+0xec2/0x1610 net/llc/af_llc.c:882
> sock_recvmsg_nosec net/socket.c:794 [inline]
> sock_recvmsg+0xd0/0x110 net/socket.c:801
> ___sys_recvmsg+0x2b6/0x680 net/socket.c:2278
> __sys_recvmmsg+0x303/0xb90 net/socket.c:2390
> do_sys_recvmmsg+0x181/0x1a0 net/socket.c:2466
> __do_sys_recvmmsg net/socket.c:2484 [inline]
> __se_sys_recvmmsg net/socket.c:2480 [inline]
> __x64_sys_recvmmsg+0xbe/0x150 net/socket.c:2480
> do_syscall_64+0x1b9/0x820 arch/x86/entry/common.c:290
> entry_SYSCALL_64_after_hwframe+0x49/0xbe
>
> The buggy address belongs to the object at ffff8801d1f6fac0
> which belongs to the cache skbuff_head_cache of size 232
> The buggy address is located 228 bytes inside of
> 232-byte region [ffff8801d1f6fac0, ffff8801d1f6fba8)
> The buggy address belongs to the page:
> page:ffffea000747dbc0 count:1 mapcount:0 mapping:ffff8801d9be7680 index:0xffff8801d1f6fe80
> flags: 0x2fffc0000000100(slab)
> raw: 02fffc0000000100 ffffea0007346e88 ffffea000705b108 ffff8801d9be7680
> raw: ffff8801d1f6fe80 ffff8801d1f6f0c0 000000010000000b 0000000000000000
> page dumped because: kasan: bad access detected
>
> Memory state around the buggy address:
> ffff8801d1f6fa80: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
> ffff8801d1f6fb00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>>ffff8801d1f6fb80: fb fb fb fb fb fc fc fc fc fc fc fc fc fc fc fc
> ^
> ffff8801d1f6fc00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> ffff8801d1f6fc80: fb fb fb fb fb fb fb fb fb fb fb fb fb fc fc fc
>
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Reported-by: syzbot <syzkaller@googlegroups.com>
Applied.
^ permalink raw reply
* Re: [PATCH net-next v2 1/6] qed: Add doorbell overflow recovery mechanism
From: David Miller @ 2018-10-23 3:05 UTC (permalink / raw)
To: Ariel.Elior; +Cc: netdev, Michal.Kalderon, Tomer.Tayar
In-Reply-To: <20181022164045.25393-2-Ariel.Elior@cavium.com>
From: Ariel Elior <Ariel.Elior@cavium.com>
Date: Mon, 22 Oct 2018 19:40:40 +0300
>
> +#ifndef writeq
> +#define writeq writeq
> +static inline void writeq(u64 val, void __iomem *reg)
> +{
> + writel(val & 0xffffffff, reg);
> + writel(val >> 32, reg + 0x4UL);
> +}
> +#endif
Please use the appropriate generic header file to achieve this, do not
reimplement it.
See include/linux/io-64-nonatomic*.h and think very carefully about
which one is appropriate.
Specifically, if a register read has side effects but only if you read
the lower or upper half you want to make sure that you use the
implementation that reads the half the doesn't trigger the side
effects first. This way the whole 64-bit value can be sampled before
status bits clear, or whatever.
Likewise for which half of a register, when written, commits the
results.
If both halfs trigger the side effect or the commit of the write, you
cannot enable your driver on 32-bit architectures.
So this is not such a simple fix where you just hack the build to pass,
you have to really think hard about what the code does, how the hardware
works, and if this can even work properly on 32-bit platforms.
Thank you.
^ permalink raw reply
* Re: [PATCH net-next 6/7] net: hns3: Add enable and process hw errors from PPP
From: Dan Carpenter @ 2018-10-23 11:28 UTC (permalink / raw)
To: kbuild, Salil Mehta
Cc: salil.mehta, mehta.salil, netdev, linux-kernel, linuxarm,
kbuild-all, lipeng321, yisen.zhuang, davem, Shiju Jose
In-Reply-To: <20181019191532.10088-7-salil.mehta@huawei.com>
Hi Shiju,
Thank you for the patch! Perhaps something to improve:
url: https://github.com/0day-ci/linux/commits/Salil-Mehta/Adds-support-of-RAS-Error-Handling-in-HNS3-Driver/20181021-183911
smatch warnings:
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c:700 hclge_log_and_clear_ppp_error() error: uninitialized symbol 'hw_err_lst3'.
# https://github.com/0day-ci/linux/commit/9a8545e85954ec55367e8881d18cc2ae95c56d98
git remote add linux-review https://github.com/0day-ci/linux
git remote update linux-review
git checkout 9a8545e85954ec55367e8881d18cc2ae95c56d98
vim +/hw_err_lst3 +700 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c
19049622e Shiju Jose 2018-10-19 653
9a8545e85 Shiju Jose 2018-10-19 654 static int hclge_log_and_clear_ppp_error(struct hclge_dev *hdev, u32 cmd,
9a8545e85 Shiju Jose 2018-10-19 655 enum hclge_err_int_type int_type)
9a8545e85 Shiju Jose 2018-10-19 656 {
9a8545e85 Shiju Jose 2018-10-19 657 enum hnae3_reset_type reset_level = HNAE3_NONE_RESET;
9a8545e85 Shiju Jose 2018-10-19 658 struct device *dev = &hdev->pdev->dev;
9a8545e85 Shiju Jose 2018-10-19 659 const struct hclge_hw_error *hw_err_lst1, *hw_err_lst2, *hw_err_lst3;
9a8545e85 Shiju Jose 2018-10-19 660 struct hclge_desc desc[2];
9a8545e85 Shiju Jose 2018-10-19 661 u32 err_sts;
9a8545e85 Shiju Jose 2018-10-19 662 int ret;
9a8545e85 Shiju Jose 2018-10-19 663
9a8545e85 Shiju Jose 2018-10-19 664 /* read PPP INT sts */
9a8545e85 Shiju Jose 2018-10-19 665 ret = hclge_cmd_query_error(hdev, &desc[0], cmd,
9a8545e85 Shiju Jose 2018-10-19 666 HCLGE_CMD_FLAG_NEXT, 5, int_type);
9a8545e85 Shiju Jose 2018-10-19 667 if (ret) {
9a8545e85 Shiju Jose 2018-10-19 668 dev_err(dev, "failed(=%d) to query PPP interrupt status\n",
9a8545e85 Shiju Jose 2018-10-19 669 ret);
9a8545e85 Shiju Jose 2018-10-19 670 return -EIO;
9a8545e85 Shiju Jose 2018-10-19 671 }
9a8545e85 Shiju Jose 2018-10-19 672
9a8545e85 Shiju Jose 2018-10-19 673 /* log error */
9a8545e85 Shiju Jose 2018-10-19 674 if (cmd == HCLGE_PPP_CMD0_INT_CMD) {
9a8545e85 Shiju Jose 2018-10-19 675 hw_err_lst1 = &hclge_ppp_mpf_int0[0];
9a8545e85 Shiju Jose 2018-10-19 676 hw_err_lst2 = &hclge_ppp_mpf_int1[0];
9a8545e85 Shiju Jose 2018-10-19 677 hw_err_lst3 = &hclge_ppp_pf_int[0];
9a8545e85 Shiju Jose 2018-10-19 678 } else if (cmd == HCLGE_PPP_CMD1_INT_CMD) {
9a8545e85 Shiju Jose 2018-10-19 679 hw_err_lst1 = &hclge_ppp_mpf_int2[0];
9a8545e85 Shiju Jose 2018-10-19 680 hw_err_lst2 = &hclge_ppp_mpf_int3[0];
Not set here.
9a8545e85 Shiju Jose 2018-10-19 681 } else {
9a8545e85 Shiju Jose 2018-10-19 682 dev_err(dev, "invalid command(=%d)\n", cmd);
9a8545e85 Shiju Jose 2018-10-19 683 return -EINVAL;
9a8545e85 Shiju Jose 2018-10-19 684 }
9a8545e85 Shiju Jose 2018-10-19 685
9a8545e85 Shiju Jose 2018-10-19 686 err_sts = le32_to_cpu(desc[0].data[2]);
9a8545e85 Shiju Jose 2018-10-19 687 if (err_sts) {
9a8545e85 Shiju Jose 2018-10-19 688 hclge_log_error(dev, hw_err_lst1, err_sts);
9a8545e85 Shiju Jose 2018-10-19 689 reset_level = HNAE3_FUNC_RESET;
9a8545e85 Shiju Jose 2018-10-19 690 }
9a8545e85 Shiju Jose 2018-10-19 691
9a8545e85 Shiju Jose 2018-10-19 692 err_sts = le32_to_cpu(desc[0].data[3]);
9a8545e85 Shiju Jose 2018-10-19 693 if (err_sts) {
9a8545e85 Shiju Jose 2018-10-19 694 hclge_log_error(dev, hw_err_lst2, err_sts);
9a8545e85 Shiju Jose 2018-10-19 695 reset_level = HNAE3_FUNC_RESET;
9a8545e85 Shiju Jose 2018-10-19 696 }
9a8545e85 Shiju Jose 2018-10-19 697
9a8545e85 Shiju Jose 2018-10-19 698 err_sts = (le32_to_cpu(desc[0].data[4]) >> 8) & 0x3;
9a8545e85 Shiju Jose 2018-10-19 699 if (err_sts) {
9a8545e85 Shiju Jose 2018-10-19 @700 hclge_log_error(dev, hw_err_lst3, err_sts);
^^^^^^^^^^^
Uninitialized.
9a8545e85 Shiju Jose 2018-10-19 701 reset_level = HNAE3_FUNC_RESET;
9a8545e85 Shiju Jose 2018-10-19 702 }
9a8545e85 Shiju Jose 2018-10-19 703
9a8545e85 Shiju Jose 2018-10-19 704 /* clear PPP INT */
9a8545e85 Shiju Jose 2018-10-19 705 ret = hclge_cmd_clear_error(hdev, &desc[0], NULL, 0,
9a8545e85 Shiju Jose 2018-10-19 706 HCLGE_CMD_FLAG_NEXT);
9a8545e85 Shiju Jose 2018-10-19 707 if (ret) {
9a8545e85 Shiju Jose 2018-10-19 708 dev_err(dev, "failed(=%d) to clear PPP interrupt status\n",
9a8545e85 Shiju Jose 2018-10-19 709 ret);
9a8545e85 Shiju Jose 2018-10-19 710 return -EIO;
9a8545e85 Shiju Jose 2018-10-19 711 }
9a8545e85 Shiju Jose 2018-10-19 712
9a8545e85 Shiju Jose 2018-10-19 713 return 0;
9a8545e85 Shiju Jose 2018-10-19 714 }
9a8545e85 Shiju Jose 2018-10-19 715
^ permalink raw reply
* Re: [PATCH v2 00/17] octeontx2-af: NPC parser and NIX blocks initialization
From: David Miller @ 2018-10-23 3:19 UTC (permalink / raw)
To: sunil.kovvuri; +Cc: netdev, arnd, linux-soc, sgoutham
In-Reply-To: <1540230964-5506-1-git-send-email-sunil.kovvuri@gmail.com>
From: sunil.kovvuri@gmail.com
Date: Mon, 22 Oct 2018 23:25:47 +0530
> From: Sunil Goutham <sgoutham@marvell.com>
>
> This patchset is a continuation to earlier submitted two patch
> series to add a new driver for Marvell's OcteonTX2 SOC's
> Resource virtualization unit (RVU) admin function driver.
>
> 1. octeontx2-af: Add RVU Admin Function driver
> https://www.spinics.net/lists/netdev/msg528272.html
> 2. octeontx2-af: NPA and NIX blocks initialization
> https://www.spinics.net/lists/netdev/msg529163.html
>
> This patch series adds more NIX block configuration logic
> and additionally adds NPC block parser profile configuration.
> In brief below is what this series adds.
> NIX block:
> - Support for PF/VF to allocate/free transmit scheduler queues,
> maintenance and their configuration.
> - Adds support for packet replication lists, only broadcast
> packets is covered for now.
> - Defines few RSS flow algorithms for HW to distribute packets.
> This is not the hash algorithsm (i.e toeplitz or crc32), here SW
> defines what fields in packet should HW take and calculate the hash.
> - Support for PF/VF to configure VTAG strip and capture capabilities.
> - Reset NIXLF statastics.
>
> NPC block:
> This block has multiple parser engines which support packet parsing
> at multiple layers and generates a parse result which is further used
> to generate a key. Based on packet field offsets in the key, SW can
> install packet forwarding rules.
> This patch series adds
> - Initial parser profile to be programmed into parser engines.
> - Default forwarding rules to forward packets to different logical
> interfaces having a NIXLF attached.
> - Support for promiscuous and multicast modes.
>
> Changes from v1:
> 1 Fixed kernel build failure when compiled with BIG_ENDIAN enabled.
> - Reported by Kbuild test robot
> 2 Fixed a warning observed when kernel is built with -Wunused-but-set-variable
Series applied.
^ permalink raw reply
* Re: [PATCH net-next] tls: Add maintainers
From: David Miller @ 2018-10-23 3:20 UTC (permalink / raw)
To: davejwatson; +Cc: netdev, borisp, aviadye, john.fastabend, daniel
In-Reply-To: <20181022193635.avvyx2e77zo6hjjm@davejwatson-mba.dhcp.thefacebook.com>
From: Dave Watson <davejwatson@fb.com>
Date: Mon, 22 Oct 2018 19:36:37 +0000
> Add John and Daniel as additional tls co-maintainers to help review
> patches and fix syzbot reports.
>
> Acked-by: John Fastabend <john.fastabend@gmail.com>
> Acked-by: Daniel Borkmann <daniel@iogearbox.net>
> Signed-off-by: Dave Watson <davejwatson@fb.com>
Applied.
^ permalink raw reply
* Re: [PATCH 0/8] Netfilter fixes for net
From: David Miller @ 2018-10-23 3:21 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel, netdev
In-Reply-To: <20181022200724.25806-1-pablo@netfilter.org>
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Mon, 22 Oct 2018 22:07:16 +0200
> The following patchset contains Netfilter fixes for your net tree:
>
> 1) rbtree lookup from control plane returns the left-hand side element
> of the range when the interval end flag is set on.
>
> 2) osf extension is not supported from the input path, reject this from
> the control plane, from Fernando Fernandez Mancera.
>
> 3) xt_TEE is leaving output interface unset due to a recent incorrect
> netns rework, from Taehee Yoo.
>
> 4) xt_TEE allows to select an interface which does not belong to this
> netnamespace, from Taehee Yoo.
>
> 5) Zero private extension area in nft_compat, just like we do in x_tables,
> otherwise we leak kernel memory to userspace.
>
> 6) Missing .checkentry and .destroy entries in new DNAT extensions breaks
> it since we never load nf_conntrack dependencies, from Paolo Abeni.
>
> 7) Do not remove flowtable hook from netns exit path, the netdevice handler
> already deals with this, also from Taehee Yoo.
>
> 8) Only cleanup flowtable entries that reside in this netnamespace, also
> from Taehee Yoo.
>
> You can pull these changes from:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git
Pulled.
^ permalink raw reply
* Re: [PATCH v3 net-next 00/11] net: dsa: microchip: Modify KSZ9477 DSA driver in preparation to add other KSZ switch drivers
From: David Miller @ 2018-10-23 3:26 UTC (permalink / raw)
To: Tristram.Ha
Cc: andrew, f.fainelli, pavel, ruediger.schmitt, UNGLinuxDriver,
netdev
In-Reply-To: <1540261575-1889-1-git-send-email-Tristram.Ha@microchip.com>
From: <Tristram.Ha@microchip.com>
Date: Mon, 22 Oct 2018 19:26:04 -0700
> This series of patches is to modify the original KSZ9477 DSA driver so
> that other KSZ switch drivers can be added and use the common code.
This doesn't apply cleanly to net-next.
And the net-next tree is now closed due to the merge window, please resubmit a
fixed series once net-next opens back up again.
Thanks.
^ permalink raw reply
* net-next is CLOSED
From: David Miller @ 2018-10-23 3:27 UTC (permalink / raw)
To: netdev
Please do not submit net-next changes until that tree opens back
up again after the merge window.
Thank you.
^ permalink raw reply
* Re: [v2,0/2] net: if_arp: use define instead of hard-coded value
From: Håkon Bugge @ 2018-10-23 12:30 UTC (permalink / raw)
To: netdev
Cc: Stephen Hemminger, David S . Miller, Kate Stewart,
Thomas Gleixner, Greg Kroah-Hartman, Philippe Ombredanne,
linux-kernel
In-Reply-To: <20181009142724.2213012-1-Haakon.Bugge@oracle.com>
> On 9 Oct 2018, at 16:27, Håkon Bugge <haakon.bugge@oracle.com> wrote:
>
> Struct arpreq contains the name of the device. All other places in the
> kernel, the define IFNAMSIZ is used to designate its size. But in
> if_arp.h, a literal constant is used.
>
> Fixed by explicitly including uapi/linu/if.h, where IFNAMSIZ is defined.
>
> The series also fixes some incorrect indents.
>
>
> v1 -> v2:
> * Include uapi/linux/if.h from if_arp.h
> * Added Stephen's t-b
>
> Håkon Bugge (2):
> net: if_arp: Fix incorrect indents
> net: if_arp: use define instead of hard-coded value
>
> include/uapi/linux/if_arp.h | 19 ++++++++++---------
> 1 file changed, 10 insertions(+), 9 deletions(-)
> ---
> 2.14.3
Just a friendly reminder.
Thxs, Håkon
>
>
> From a36b99413ea5beca1539f4faf065f33c7c19e6a5 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?H=C3=A5kon=20Bugge?= <Haakon.Bugge@oracle.com>
> Date: Fri, 21 Sep 2018 11:28:36 +0200
> Subject: [PATCH 0/2]
> MIME-Version: 1.0
> Content-Type: text/plain; charset=UTF-8
> Content-Transfer-Encoding: 8bit
>
> Struct arpreq contains the name of the device. All other places in the
> kernel, the define IFNAMSIZ is used to designate its size. But in
> if_arp.h, a literal constant is used.
>
> As it could be good reasons to use constants instead of the defines in
> include files under uapi, it seems to be OK to use the define here,
> without opening a can of worms in user-land.
>
> This because if_arp.h includes netdevice.h, which also uses
> IFNAMSIZ. For the distros I have checked, this also holds true for the
> use-land side.
>
> The series also fixes some incorrect indents.
>
> Håkon Bugge (2):
> net: if_arp: Fix incorrect indents
> net: if_arp: use define instead of hard-coded value
>
> include/uapi/linux/if_arp.h | 18 +++++++++---------
> 1 file changed, 9 insertions(+), 9 deletions(-)
>
> --
> 2.14.3
^ permalink raw reply
* Re: [PATCH net-next 1/3] net/sock: factor out dequeue/peek with offset code
From: Alexei Starovoitov @ 2018-10-23 4:49 UTC (permalink / raw)
To: Paolo Abeni; +Cc: netdev, David S. Miller, Eric Dumazet, kafai
In-Reply-To: <503e324ecd4085f256474df1a352a92814fd29f4.1494837879.git.pabeni@redhat.com>
On Mon, May 15, 2017 at 11:01:42AM +0200, Paolo Abeni wrote:
> And update __sk_queue_drop_skb() to work on the specified queue.
> This will help the udp protocol to use an additional private
> rx queue in a later patch.
>
> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
> ---
> include/linux/skbuff.h | 7 ++++
> include/net/sock.h | 4 +--
> net/core/datagram.c | 90 ++++++++++++++++++++++++++++----------------------
> 3 files changed, 60 insertions(+), 41 deletions(-)
>
> diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
> index a098d95..bfc7892 100644
> --- a/include/linux/skbuff.h
> +++ b/include/linux/skbuff.h
> @@ -3056,6 +3056,13 @@ static inline void skb_frag_list_init(struct sk_buff *skb)
>
> int __skb_wait_for_more_packets(struct sock *sk, int *err, long *timeo_p,
> const struct sk_buff *skb);
> +struct sk_buff *__skb_try_recv_from_queue(struct sock *sk,
> + struct sk_buff_head *queue,
> + unsigned int flags,
> + void (*destructor)(struct sock *sk,
> + struct sk_buff *skb),
> + int *peeked, int *off, int *err,
> + struct sk_buff **last);
> struct sk_buff *__skb_try_recv_datagram(struct sock *sk, unsigned flags,
> void (*destructor)(struct sock *sk,
> struct sk_buff *skb),
> diff --git a/include/net/sock.h b/include/net/sock.h
> index 66349e4..49d226f 100644
> --- a/include/net/sock.h
> +++ b/include/net/sock.h
> @@ -2035,8 +2035,8 @@ void sk_reset_timer(struct sock *sk, struct timer_list *timer,
>
> void sk_stop_timer(struct sock *sk, struct timer_list *timer);
>
> -int __sk_queue_drop_skb(struct sock *sk, struct sk_buff *skb,
> - unsigned int flags,
> +int __sk_queue_drop_skb(struct sock *sk, struct sk_buff_head *sk_queue,
> + struct sk_buff *skb, unsigned int flags,
> void (*destructor)(struct sock *sk,
> struct sk_buff *skb));
> int __sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
> diff --git a/net/core/datagram.c b/net/core/datagram.c
> index db1866f2..a4592b4 100644
> --- a/net/core/datagram.c
> +++ b/net/core/datagram.c
> @@ -161,6 +161,43 @@ static struct sk_buff *skb_set_peeked(struct sk_buff *skb)
> return skb;
> }
>
> +struct sk_buff *__skb_try_recv_from_queue(struct sock *sk,
> + struct sk_buff_head *queue,
> + unsigned int flags,
> + void (*destructor)(struct sock *sk,
> + struct sk_buff *skb),
> + int *peeked, int *off, int *err,
> + struct sk_buff **last)
> +{
> + struct sk_buff *skb;
> +
> + *last = queue->prev;
this refactoring changed the behavior.
Now queue->prev is returned as last.
Whereas it was *last = queue before.
> + skb_queue_walk(queue, skb) {
and *last = skb assignment is gone too.
Was this intentional ? Is this the right behavior?
> + if (flags & MSG_PEEK) {
> + if (*off >= skb->len && (skb->len || *off ||
> + skb->peeked)) {
> + *off -= skb->len;
> + continue;
> + }
> + if (!skb->len) {
> + skb = skb_set_peeked(skb);
> + if (unlikely(IS_ERR(skb))) {
> + *err = PTR_ERR(skb);
> + return skb;
> + }
> + }
> + *peeked = 1;
> + atomic_inc(&skb->users);
> + } else {
> + __skb_unlink(skb, queue);
> + if (destructor)
> + destructor(sk, skb);
> + }
> + return skb;
> + }
> + return NULL;
> +}
> +
> /**
> * __skb_try_recv_datagram - Receive a datagram skbuff
> * @sk: socket
> @@ -216,46 +253,20 @@ struct sk_buff *__skb_try_recv_datagram(struct sock *sk, unsigned int flags,
>
> *peeked = 0;
> do {
> + int _off = *off;
> +
> /* Again only user level code calls this function, so nothing
> * interrupt level will suddenly eat the receive_queue.
> *
> * Look at current nfs client by the way...
> * However, this function was correct in any case. 8)
> */
> - int _off = *off;
> -
> - *last = (struct sk_buff *)queue;
> spin_lock_irqsave(&queue->lock, cpu_flags);
> - skb_queue_walk(queue, skb) {
> - *last = skb;
> - if (flags & MSG_PEEK) {
> - if (_off >= skb->len && (skb->len || _off ||
> - skb->peeked)) {
> - _off -= skb->len;
> - continue;
> - }
> - if (!skb->len) {
> - skb = skb_set_peeked(skb);
> - if (IS_ERR(skb)) {
> - error = PTR_ERR(skb);
> - spin_unlock_irqrestore(&queue->lock,
> - cpu_flags);
> - goto no_packet;
> - }
> - }
> - *peeked = 1;
> - atomic_inc(&skb->users);
> - } else {
> - __skb_unlink(skb, queue);
> - if (destructor)
> - destructor(sk, skb);
> - }
> - spin_unlock_irqrestore(&queue->lock, cpu_flags);
> - *off = _off;
> - return skb;
> - }
> -
> + skb = __skb_try_recv_from_queue(sk, queue, flags, destructor,
> + peeked, &_off, err, last);
> spin_unlock_irqrestore(&queue->lock, cpu_flags);
> + if (skb)
> + return skb;
>
> if (!sk_can_busy_loop(sk))
> break;
> @@ -335,8 +346,8 @@ void __skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb, int len)
> }
> EXPORT_SYMBOL(__skb_free_datagram_locked);
>
> -int __sk_queue_drop_skb(struct sock *sk, struct sk_buff *skb,
> - unsigned int flags,
> +int __sk_queue_drop_skb(struct sock *sk, struct sk_buff_head *sk_queue,
> + struct sk_buff *skb, unsigned int flags,
> void (*destructor)(struct sock *sk,
> struct sk_buff *skb))
> {
> @@ -344,15 +355,15 @@ int __sk_queue_drop_skb(struct sock *sk, struct sk_buff *skb,
>
> if (flags & MSG_PEEK) {
> err = -ENOENT;
> - spin_lock_bh(&sk->sk_receive_queue.lock);
> - if (skb == skb_peek(&sk->sk_receive_queue)) {
> - __skb_unlink(skb, &sk->sk_receive_queue);
> + spin_lock_bh(&sk_queue->lock);
> + if (skb == skb_peek(sk_queue)) {
> + __skb_unlink(skb, sk_queue);
> atomic_dec(&skb->users);
> if (destructor)
> destructor(sk, skb);
> err = 0;
> }
> - spin_unlock_bh(&sk->sk_receive_queue.lock);
> + spin_unlock_bh(&sk_queue->lock);
> }
>
> atomic_inc(&sk->sk_drops);
> @@ -383,7 +394,8 @@ EXPORT_SYMBOL(__sk_queue_drop_skb);
>
> int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags)
> {
> - int err = __sk_queue_drop_skb(sk, skb, flags, NULL);
> + int err = __sk_queue_drop_skb(sk, &sk->sk_receive_queue, skb, flags,
> + NULL);
>
> kfree_skb(skb);
> sk_mem_reclaim_partial(sk);
> --
> 2.9.3
>
^ permalink raw reply
* Re: [PATCH net-next 1/6] qed: Add doorbell overflow recovery mechanism
From: kbuild test robot @ 2018-10-23 5:15 UTC (permalink / raw)
To: Ariel Elior
Cc: kbuild-all, davem, netdev, Ariel Elior, Michal Kalderon,
Tomer Tayar
In-Reply-To: <20181022122743.20384-2-Ariel.Elior@cavium.com>
[-- Attachment #1: Type: text/plain, Size: 2837 bytes --]
Hi Ariel,
I love your patch! Yet something to improve:
[auto build test ERROR on net-next/master]
url: https://github.com/0day-ci/linux/commits/Ariel-Elior/qed-Doorbell-overflow-recovery/20181022-212749
config: i386-allyesconfig (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=i386
All errors (new ones prefixed by >>):
drivers/net/ethernet/qlogic/qed/qed_dev.c: In function 'qed_db_recovery_ring':
>> drivers/net/ethernet/qlogic/qed/qed_dev.c:342:4: error: implicit declaration of function 'writeq'; did you mean 'writel'? [-Werror=implicit-function-declaration]
DIRECT_REG_WR64(db_entry->db_addr,
^~~~~~
writel
cc1: some warnings being treated as errors
vim +342 drivers/net/ethernet/qlogic/qed/qed_dev.c
300
301 /* Ring the doorbell of a single doorbell recovery entry */
302 static void qed_db_recovery_ring(struct qed_hwfn *p_hwfn,
303 struct qed_db_recovery_entry *db_entry,
304 enum qed_db_rec_exec db_exec)
305 {
306 if (db_exec != DB_REC_ONCE) {
307 /* Print according to width */
308 if (db_entry->db_width == DB_REC_WIDTH_32B) {
309 DP_VERBOSE(p_hwfn, QED_MSG_SPQ,
310 "%s doorbell address %p data %x\n",
311 db_exec == DB_REC_DRY_RUN ?
312 "would have rung" : "ringing",
313 db_entry->db_addr,
314 *(u32 *)db_entry->db_data);
315 } else {
316 DP_VERBOSE(p_hwfn, QED_MSG_SPQ,
317 "%s doorbell address %p data %llx\n",
318 db_exec == DB_REC_DRY_RUN ?
319 "would have rung" : "ringing",
320 db_entry->db_addr,
321 *(u64 *)(db_entry->db_data));
322 }
323 }
324
325 /* Sanity */
326 if (!qed_db_rec_sanity(p_hwfn->cdev, db_entry->db_addr,
327 db_entry->db_data))
328 return;
329
330 /* Flush the write combined buffer. Since there are multiple doorbelling
331 * entities using the same address, if we don't flush, a transaction
332 * could be lost.
333 */
334 wmb();
335
336 /* Ring the doorbell */
337 if (db_exec == DB_REC_REAL_DEAL || db_exec == DB_REC_ONCE) {
338 if (db_entry->db_width == DB_REC_WIDTH_32B)
339 DIRECT_REG_WR(db_entry->db_addr,
340 *(u32 *)(db_entry->db_data));
341 else
> 342 DIRECT_REG_WR64(db_entry->db_addr,
343 *(u64 *)(db_entry->db_data));
344 }
345
346 /* Flush the write combined buffer. Next doorbell may come from a
347 * different entity to the same address...
348 */
349 wmb();
350 }
351
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 64635 bytes --]
^ permalink raw reply
* RE: [PATCH net-next v2 1/6] qed: Add doorbell overflow recovery mechanism
From: Elior, Ariel @ 2018-10-23 5:16 UTC (permalink / raw)
To: David Miller; +Cc: netdev@vger.kernel.org, Kalderon, Michal, Tayar, Tomer
In-Reply-To: <20181022.200559.1672641132565115543.davem@davemloft.net>
>
> > +#ifndef writeq
> > +#define writeq writeq
> > +static inline void writeq(u64 val, void __iomem *reg)
> > +{
> > + writel(val & 0xffffffff, reg);
> > + writel(val >> 32, reg + 0x4UL);
> > +}
> > +#endif
>
> Please use the appropriate generic header file to achieve this, do not
> reimplement it.
>
> See include/linux/io-64-nonatomic*.h and think very carefully about
> which one is appropriate.
>
> Specifically, if a register read has side effects but only if you read
> the lower or upper half you want to make sure that you use the
> implementation that reads the half the doesn't trigger the side
> effects first. This way the whole 64-bit value can be sampled before
> status bits clear, or whatever.
>
> Likewise for which half of a register, when written, commits the
> results.
>
> If both halfs trigger the side effect or the commit of the write, you
> cannot enable your driver on 32-bit architectures.
>
> So this is not such a simple fix where you just hack the build to pass,
> you have to really think hard about what the code does, how the hardware
> works, and if this can even work properly on 32-bit platforms.
>
> Thank you.
Thanks for pointing out the generic implementation. In our drivers we only use
The 64b macros for a single purpose - writing the rdma CQ doorbells. It will not
be used in any other register access. In this case the "lower and then upper" is
the correct behavior for us. I will send a v3 using the generic implementation.
Thanks,
Ariel
^ permalink raw reply
* [PATCH net-next 0/6 v2] qed*: Doorbell overflow recovery
From: Ariel Elior @ 2018-10-23 5:35 UTC (permalink / raw)
To: davem; +Cc: netdev, Ariel Elior, Michal Kalderon, Tomer Tayar
Doorbell Overflow
If sufficient CPU cores will send doorbells at a sufficiently high rate, they
can cause an overflow in the doorbell queue block message fifo. When fill level
reaches maximum, the device stops accepting all doorbells from that PF until a
recovery procedure has taken place.
Doorbell Overflow Recovery
The recovery procedure basically means resending the last doorbell for every
doorbelling entity. A doorbelling entity is anything which may send doorbells:
L2 tx ring, rdma sq/rq/cq, light l2, vf l2 tx ring, spq, etc. This relies on
the design assumption that all doorbells are aggregative, so last doorbell
carries the information of all previous doorbells.
APIs
All doorbelling entities need to register with the mechanism before sending
doorbells. The registration entails providing the doorbell address the entity
would be using, and a virtual address where last doorbell data can be found.
Typically fastpath structures already have this construct.
Executing the recovery procedure
Handling the attentions, iterating over all the registered entities and
resending their doorbells, is all handled within qed core module.
Relevance
All doorbelling entities in all protocols need to register with the mechanism,
via the new APIs. Technically this is quite simple (just call the API). Some
protocol fastpath implementation may not have the doorbell data stored anywhere
(compute it from scratch every time) and will have to add such a place.
This is rare and is also better practice (save some cycles on the fastpath).
Performance Penalty
No performance penalty should incur as a result of this feature. If anything
performance can improve by avoiding recalcualtion of doorbell data everytime
doorbell is sent (in some flows).
Add the database used to register doorbelling entities, and APIs for adding
and deleting entries, and logic for traversing the database and doorbelling
once on behalf of all entities.
Please consider applying to net-next.
Thanks,
Ariel
Signed-off-by: Ariel Elior <Ariel.Elior@cavium.com>
Signed-off-by: Michal Kalderon <Michal.Kalderon@cavium.com>
Signed-off-by: Tomer Tayar <Tomer.Tayar@cavium.com>
v1->v2:
-------
Add support for ARCH=i386 (definition of writeq)
v2->v3:
-------
Use generic writeq implementation in
io-64-nonatomic-lo-hi.h instead of reimplementing.
Ariel Elior (6):
qed: Add doorbell overflow recovery mechanism
qed: Use the doorbell overflow recovery mechanism in case of doorbell
overflow
qed: Register slowpath queue doorbell with doorbell overflow recovery
mechanism
qed: Register light L2 queues with doorbell overflow recovery
mechanism
qed: Expose the doorbell overflow recovery mechanism to the protocol
drivers
qede: Register l2 queues with doorbell overflow recovery mechanism
drivers/net/ethernet/qlogic/qed/qed.h | 31 ++-
drivers/net/ethernet/qlogic/qed/qed_dev.c | 334 ++++++++++++++++++++++++-
drivers/net/ethernet/qlogic/qed/qed_dev_api.h | 28 +++
drivers/net/ethernet/qlogic/qed/qed_int.c | 152 +++++++++--
drivers/net/ethernet/qlogic/qed/qed_int.h | 10 +
drivers/net/ethernet/qlogic/qed/qed_ll2.c | 30 ++-
drivers/net/ethernet/qlogic/qed/qed_ll2.h | 1 +
drivers/net/ethernet/qlogic/qed/qed_main.c | 66 ++++-
drivers/net/ethernet/qlogic/qed/qed_reg_addr.h | 50 ++++
drivers/net/ethernet/qlogic/qed/qed_sp.h | 4 +-
drivers/net/ethernet/qlogic/qed/qed_spq.c | 22 ++
drivers/net/ethernet/qlogic/qede/qede_main.c | 9 +
include/linux/qed/qed_if.h | 42 ++++
13 files changed, 744 insertions(+), 35 deletions(-)
--
1.8.3.1
^ permalink raw reply
* [PATCH net-next v3 1/6] qed: Add doorbell overflow recovery mechanism
From: Ariel Elior @ 2018-10-23 5:35 UTC (permalink / raw)
To: davem; +Cc: netdev, Ariel Elior, Michal Kalderon, Tomer Tayar
In-Reply-To: <20181023053549.5591-1-Ariel.Elior@cavium.com>
Add the database used to register doorbelling entities, and APIs for adding
and deleting entries, and logic for traversing the database and doorbelling
once on behalf of all entities.
Signed-off-by: Ariel Elior <Ariel.Elior@cavium.com>
Signed-off-by: Michal Kalderon <Michal.Kalderon@cavium.com>
Signed-off-by: Tomer Tayar <Tomer.Tayar@cavium.com>
---
drivers/net/ethernet/qlogic/qed/qed.h | 17 ++
drivers/net/ethernet/qlogic/qed/qed_dev.c | 320 ++++++++++++++++++++++++++
drivers/net/ethernet/qlogic/qed/qed_dev_api.h | 28 +++
include/linux/qed/qed_if.h | 14 ++
4 files changed, 379 insertions(+)
diff --git a/drivers/net/ethernet/qlogic/qed/qed.h b/drivers/net/ethernet/qlogic/qed/qed.h
index 5f0962d..882279e 100644
--- a/drivers/net/ethernet/qlogic/qed/qed.h
+++ b/drivers/net/ethernet/qlogic/qed/qed.h
@@ -296,6 +296,12 @@ enum qed_wol_support {
QED_WOL_SUPPORT_PME,
};
+enum qed_db_rec_exec {
+ DB_REC_DRY_RUN,
+ DB_REC_REAL_DEAL,
+ DB_REC_ONCE,
+};
+
struct qed_hw_info {
/* PCI personality */
enum qed_pci_personality personality;
@@ -425,6 +431,14 @@ struct qed_qm_info {
u8 num_pf_rls;
};
+struct qed_db_recovery_info {
+ struct list_head list;
+
+ /* Lock to protect the doorbell recovery mechanism list */
+ spinlock_t lock;
+ u32 db_recovery_counter;
+};
+
struct storm_stats {
u32 address;
u32 len;
@@ -640,6 +654,9 @@ struct qed_hwfn {
/* L2-related */
struct qed_l2_info *p_l2_info;
+ /* Mechanism for recovering from doorbell drop */
+ struct qed_db_recovery_info db_recovery_info;
+
/* Nvm images number and attributes */
struct qed_nvm_image_info nvm_info;
diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c
index 7ceb2b9..a63f87f 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dev.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c
@@ -66,6 +66,318 @@
static DEFINE_SPINLOCK(qm_lock);
+/******************** Doorbell Recovery *******************/
+/* The doorbell recovery mechanism consists of a list of entries which represent
+ * doorbelling entities (l2 queues, roce sq/rq/cqs, the slowpath spq, etc). Each
+ * entity needs to register with the mechanism and provide the parameters
+ * describing it's doorbell, including a location where last used doorbell data
+ * can be found. The doorbell execute function will traverse the list and
+ * doorbell all of the registered entries.
+ */
+struct qed_db_recovery_entry {
+ struct list_head list_entry;
+ void __iomem *db_addr;
+ void *db_data;
+ enum qed_db_rec_width db_width;
+ enum qed_db_rec_space db_space;
+ u8 hwfn_idx;
+};
+
+/* Display a single doorbell recovery entry */
+static void qed_db_recovery_dp_entry(struct qed_hwfn *p_hwfn,
+ struct qed_db_recovery_entry *db_entry,
+ char *action)
+{
+ DP_VERBOSE(p_hwfn,
+ QED_MSG_SPQ,
+ "(%s: db_entry %p, addr %p, data %p, width %s, %s space, hwfn %d)\n",
+ action,
+ db_entry,
+ db_entry->db_addr,
+ db_entry->db_data,
+ db_entry->db_width == DB_REC_WIDTH_32B ? "32b" : "64b",
+ db_entry->db_space == DB_REC_USER ? "user" : "kernel",
+ db_entry->hwfn_idx);
+}
+
+/* Doorbell address sanity (address within doorbell bar range) */
+static bool qed_db_rec_sanity(struct qed_dev *cdev,
+ void __iomem *db_addr, void *db_data)
+{
+ /* Make sure doorbell address is within the doorbell bar */
+ if (db_addr < cdev->doorbells ||
+ (u8 __iomem *)db_addr >
+ (u8 __iomem *)cdev->doorbells + cdev->db_size) {
+ WARN(true,
+ "Illegal doorbell address: %p. Legal range for doorbell addresses is [%p..%p]\n",
+ db_addr,
+ cdev->doorbells,
+ (u8 __iomem *)cdev->doorbells + cdev->db_size);
+ return false;
+ }
+
+ /* ake sure doorbell data pointer is not null */
+ if (!db_data) {
+ WARN(true, "Illegal doorbell data pointer: %p", db_data);
+ return false;
+ }
+
+ return true;
+}
+
+/* Find hwfn according to the doorbell address */
+static struct qed_hwfn *qed_db_rec_find_hwfn(struct qed_dev *cdev,
+ void __iomem *db_addr)
+{
+ struct qed_hwfn *p_hwfn;
+
+ /* In CMT doorbell bar is split down the middle between engine 0 and enigne 1 */
+ if (cdev->num_hwfns > 1)
+ p_hwfn = db_addr < cdev->hwfns[1].doorbells ?
+ &cdev->hwfns[0] : &cdev->hwfns[1];
+ else
+ p_hwfn = QED_LEADING_HWFN(cdev);
+
+ return p_hwfn;
+}
+
+/* Add a new entry to the doorbell recovery mechanism */
+int qed_db_recovery_add(struct qed_dev *cdev,
+ void __iomem *db_addr,
+ void *db_data,
+ enum qed_db_rec_width db_width,
+ enum qed_db_rec_space db_space)
+{
+ struct qed_db_recovery_entry *db_entry;
+ struct qed_hwfn *p_hwfn;
+
+ /* Shortcircuit VFs, for now */
+ if (IS_VF(cdev)) {
+ DP_VERBOSE(cdev,
+ QED_MSG_IOV, "db recovery - skipping VF doorbell\n");
+ return 0;
+ }
+
+ /* Sanitize doorbell address */
+ if (!qed_db_rec_sanity(cdev, db_addr, db_data))
+ return -EINVAL;
+
+ /* Obtain hwfn from doorbell address */
+ p_hwfn = qed_db_rec_find_hwfn(cdev, db_addr);
+
+ /* Create entry */
+ db_entry = kzalloc(sizeof(*db_entry), GFP_KERNEL);
+ if (!db_entry) {
+ DP_NOTICE(cdev, "Failed to allocate a db recovery entry\n");
+ return -ENOMEM;
+ }
+
+ /* Populate entry */
+ db_entry->db_addr = db_addr;
+ db_entry->db_data = db_data;
+ db_entry->db_width = db_width;
+ db_entry->db_space = db_space;
+ db_entry->hwfn_idx = p_hwfn->my_id;
+
+ /* Display */
+ qed_db_recovery_dp_entry(p_hwfn, db_entry, "Adding");
+
+ /* Protect the list */
+ spin_lock_bh(&p_hwfn->db_recovery_info.lock);
+ list_add_tail(&db_entry->list_entry, &p_hwfn->db_recovery_info.list);
+ spin_unlock_bh(&p_hwfn->db_recovery_info.lock);
+
+ return 0;
+}
+
+/* Remove an entry from the doorbell recovery mechanism */
+int qed_db_recovery_del(struct qed_dev *cdev,
+ void __iomem *db_addr, void *db_data)
+{
+ struct qed_db_recovery_entry *db_entry = NULL;
+ struct qed_hwfn *p_hwfn;
+ int rc = -EINVAL;
+
+ /* Shortcircuit VFs, for now */
+ if (IS_VF(cdev)) {
+ DP_VERBOSE(cdev,
+ QED_MSG_IOV, "db recovery - skipping VF doorbell\n");
+ return 0;
+ }
+
+ /* Sanitize doorbell address */
+ if (!qed_db_rec_sanity(cdev, db_addr, db_data))
+ return -EINVAL;
+
+ /* Obtain hwfn from doorbell address */
+ p_hwfn = qed_db_rec_find_hwfn(cdev, db_addr);
+
+ /* Protect the list */
+ spin_lock_bh(&p_hwfn->db_recovery_info.lock);
+ list_for_each_entry(db_entry,
+ &p_hwfn->db_recovery_info.list, list_entry) {
+ /* search according to db_data addr since db_addr is not unique (roce) */
+ if (db_entry->db_data == db_data) {
+ qed_db_recovery_dp_entry(p_hwfn, db_entry, "Deleting");
+ list_del(&db_entry->list_entry);
+ rc = 0;
+ break;
+ }
+ }
+
+ spin_unlock_bh(&p_hwfn->db_recovery_info.lock);
+
+ if (rc == -EINVAL)
+
+ DP_NOTICE(p_hwfn,
+ "Failed to find element in list. Key (db_data addr) was %p. db_addr was %p\n",
+ db_data, db_addr);
+ else
+ kfree(db_entry);
+
+ return rc;
+}
+
+/* Initialize the doorbell recovery mechanism */
+static int qed_db_recovery_setup(struct qed_hwfn *p_hwfn)
+{
+ DP_VERBOSE(p_hwfn, QED_MSG_SPQ, "Setting up db recovery\n");
+
+ /* Make sure db_size was set in cdev */
+ if (!p_hwfn->cdev->db_size) {
+ DP_ERR(p_hwfn->cdev, "db_size not set\n");
+ return -EINVAL;
+ }
+
+ INIT_LIST_HEAD(&p_hwfn->db_recovery_info.list);
+ spin_lock_init(&p_hwfn->db_recovery_info.lock);
+ p_hwfn->db_recovery_info.db_recovery_counter = 0;
+
+ return 0;
+}
+
+/* Destroy the doorbell recovery mechanism */
+static void qed_db_recovery_teardown(struct qed_hwfn *p_hwfn)
+{
+ struct qed_db_recovery_entry *db_entry = NULL;
+
+ DP_VERBOSE(p_hwfn, QED_MSG_SPQ, "Tearing down db recovery\n");
+ if (!list_empty(&p_hwfn->db_recovery_info.list)) {
+ DP_VERBOSE(p_hwfn,
+ QED_MSG_SPQ,
+ "Doorbell Recovery teardown found the doorbell recovery list was not empty (Expected in disorderly driver unload (e.g. recovery) otherwise this probably means some flow forgot to db_recovery_del). Prepare to purge doorbell recovery list...\n");
+ while (!list_empty(&p_hwfn->db_recovery_info.list)) {
+ db_entry =
+ list_first_entry(&p_hwfn->db_recovery_info.list,
+ struct qed_db_recovery_entry,
+ list_entry);
+ qed_db_recovery_dp_entry(p_hwfn, db_entry, "Purging");
+ list_del(&db_entry->list_entry);
+ kfree(db_entry);
+ }
+ }
+ p_hwfn->db_recovery_info.db_recovery_counter = 0;
+}
+
+/* Print the content of the doorbell recovery mechanism */
+void qed_db_recovery_dp(struct qed_hwfn *p_hwfn)
+{
+ struct qed_db_recovery_entry *db_entry = NULL;
+
+ DP_NOTICE(p_hwfn,
+ "Dispalying doorbell recovery database. Counter was %d\n",
+ p_hwfn->db_recovery_info.db_recovery_counter);
+
+ /* Protect the list */
+ spin_lock_bh(&p_hwfn->db_recovery_info.lock);
+ list_for_each_entry(db_entry,
+ &p_hwfn->db_recovery_info.list, list_entry) {
+ qed_db_recovery_dp_entry(p_hwfn, db_entry, "Printing");
+ }
+
+ spin_unlock_bh(&p_hwfn->db_recovery_info.lock);
+}
+
+/* Ring the doorbell of a single doorbell recovery entry */
+static void qed_db_recovery_ring(struct qed_hwfn *p_hwfn,
+ struct qed_db_recovery_entry *db_entry,
+ enum qed_db_rec_exec db_exec)
+{
+ if (db_exec != DB_REC_ONCE) {
+ /* Print according to width */
+ if (db_entry->db_width == DB_REC_WIDTH_32B) {
+ DP_VERBOSE(p_hwfn, QED_MSG_SPQ,
+ "%s doorbell address %p data %x\n",
+ db_exec == DB_REC_DRY_RUN ?
+ "would have rung" : "ringing",
+ db_entry->db_addr,
+ *(u32 *)db_entry->db_data);
+ } else {
+ DP_VERBOSE(p_hwfn, QED_MSG_SPQ,
+ "%s doorbell address %p data %llx\n",
+ db_exec == DB_REC_DRY_RUN ?
+ "would have rung" : "ringing",
+ db_entry->db_addr,
+ *(u64 *)(db_entry->db_data));
+ }
+ }
+
+ /* Sanity */
+ if (!qed_db_rec_sanity(p_hwfn->cdev, db_entry->db_addr,
+ db_entry->db_data))
+ return;
+
+ /* Flush the write combined buffer. Since there are multiple doorbelling
+ * entities using the same address, if we don't flush, a transaction
+ * could be lost.
+ */
+ wmb();
+
+ /* Ring the doorbell */
+ if (db_exec == DB_REC_REAL_DEAL || db_exec == DB_REC_ONCE) {
+ if (db_entry->db_width == DB_REC_WIDTH_32B)
+ DIRECT_REG_WR(db_entry->db_addr,
+ *(u32 *)(db_entry->db_data));
+ else
+ DIRECT_REG_WR64(db_entry->db_addr,
+ *(u64 *)(db_entry->db_data));
+ }
+
+ /* Flush the write combined buffer. Next doorbell may come from a
+ * different entity to the same address...
+ */
+ wmb();
+}
+
+/* Traverse the doorbell recovery entry list and ring all the doorbells */
+void qed_db_recovery_execute(struct qed_hwfn *p_hwfn,
+ enum qed_db_rec_exec db_exec)
+{
+ struct qed_db_recovery_entry *db_entry = NULL;
+
+ if (db_exec != DB_REC_ONCE) {
+ DP_NOTICE(p_hwfn,
+ "Executing doorbell recovery. Counter was %d\n",
+ p_hwfn->db_recovery_info.db_recovery_counter);
+
+ /* Track amount of times recovery was executed */
+ p_hwfn->db_recovery_info.db_recovery_counter++;
+ }
+
+ /* Protect the list */
+ spin_lock_bh(&p_hwfn->db_recovery_info.lock);
+ list_for_each_entry(db_entry,
+ &p_hwfn->db_recovery_info.list, list_entry) {
+ qed_db_recovery_ring(p_hwfn, db_entry, db_exec);
+ if (db_exec == DB_REC_ONCE)
+ break;
+ }
+
+ spin_unlock_bh(&p_hwfn->db_recovery_info.lock);
+}
+
+/******************** Doorbell Recovery end ****************/
+
#define QED_MIN_DPIS (4)
#define QED_MIN_PWM_REGION (QED_WID_SIZE * QED_MIN_DPIS)
@@ -190,6 +502,9 @@ void qed_resc_free(struct qed_dev *cdev)
qed_dmae_info_free(p_hwfn);
qed_dcbx_info_free(p_hwfn);
qed_dbg_user_data_free(p_hwfn);
+
+ /* Destroy doorbell recovery mechanism */
+ qed_db_recovery_teardown(p_hwfn);
}
}
@@ -946,6 +1261,11 @@ int qed_resc_alloc(struct qed_dev *cdev)
struct qed_hwfn *p_hwfn = &cdev->hwfns[i];
u32 n_eqes, num_cons;
+ /* Initialize the doorbell recovery mechanism */
+ rc = qed_db_recovery_setup(p_hwfn);
+ if (rc)
+ goto alloc_err;
+
/* First allocate the context manager structure */
rc = qed_cxt_mngr_alloc(p_hwfn);
if (rc)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev_api.h b/drivers/net/ethernet/qlogic/qed/qed_dev_api.h
index defdda1..acccd85 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dev_api.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_dev_api.h
@@ -472,6 +472,34 @@ int qed_final_cleanup(struct qed_hwfn *p_hwfn,
int
qed_set_queue_coalesce(u16 rx_coal, u16 tx_coal, void *p_handle);
+/**
+ * @brief db_recovery_add - add doorbell information to the doorbell
+ * recovery mechanism.
+ *
+ * @param cdev
+ * @param db_addr - doorbell address
+ * @param db_data - address of where db_data is stored
+ * @param db_width - doorbell is 32b pr 64b
+ * @param db_space - doorbell recovery addresses are user or kernel space
+ */
+int qed_db_recovery_add(struct qed_dev *cdev,
+ void __iomem *db_addr,
+ void *db_data,
+ enum qed_db_rec_width db_width,
+ enum qed_db_rec_space db_space);
+
+/**
+ * @brief db_recovery_del - remove doorbell information from the doorbell
+ * recovery mechanism. db_data serves as key (db_addr is not unique).
+ *
+ * @param cdev
+ * @param db_addr - doorbell address
+ * @param db_data - address where db_data is stored. Serves as key for the
+ * entry to delete.
+ */
+int qed_db_recovery_del(struct qed_dev *cdev,
+ void __iomem *db_addr, void *db_data);
+
const char *qed_hw_get_resc_name(enum qed_resources res_id);
#endif
diff --git a/include/linux/qed/qed_if.h b/include/linux/qed/qed_if.h
index dee3c9c..41382e7 100644
--- a/include/linux/qed/qed_if.h
+++ b/include/linux/qed/qed_if.h
@@ -47,6 +47,7 @@
#include <linux/slab.h>
#include <linux/qed/common_hsi.h>
#include <linux/qed/qed_chain.h>
+#include <linux/io-64-nonatomic-lo-hi.h>
enum dcbx_protocol_type {
DCBX_PROTOCOL_ISCSI,
@@ -448,11 +449,24 @@ struct qed_mfw_tlv_iscsi {
bool tx_bytes_set;
};
+enum qed_db_rec_width {
+ DB_REC_WIDTH_32B,
+ DB_REC_WIDTH_64B,
+};
+
+enum qed_db_rec_space {
+ DB_REC_KERNEL,
+ DB_REC_USER,
+};
+
#define DIRECT_REG_WR(reg_addr, val) writel((u32)val, \
(void __iomem *)(reg_addr))
#define DIRECT_REG_RD(reg_addr) readl((void __iomem *)(reg_addr))
+#define DIRECT_REG_WR64(reg_addr, val) writeq((u32)val, \
+ (void __iomem *)(reg_addr))
+
#define QED_COALESCE_MAX 0x1FF
#define QED_DEFAULT_RX_USECS 12
#define QED_DEFAULT_TX_USECS 48
--
1.8.3.1
^ permalink raw reply related
* [PATCH net-next v3 2/6] qed: Use the doorbell overflow recovery mechanism in case of doorbell overflow
From: Ariel Elior @ 2018-10-23 5:35 UTC (permalink / raw)
To: davem; +Cc: netdev, Ariel Elior, Michal Kalderon, Tomer Tayar
In-Reply-To: <20181023053549.5591-1-Ariel.Elior@cavium.com>
In case of an attention from the doorbell queue block, analyze the HW
indications. In case of a doorbell overflow, execute a doorbell recovery.
Since there can be spurious indications (race conditions between multiple PFs),
schedule a periodic task for checking whether a doorbell overflow may have been
missed. After a set time with no indications, terminate the periodic task.
Signed-off-by: Ariel Elior <Ariel.Elior@cavium.com>
Signed-off-by: Michal Kalderon <Michal.Kalderon@cavium.com>
Signed-off-by: Tomer Tayar <Tomer.Tayar@cavium.com>
---
drivers/net/ethernet/qlogic/qed/qed.h | 14 ++-
drivers/net/ethernet/qlogic/qed/qed_dev.c | 14 ++-
drivers/net/ethernet/qlogic/qed/qed_int.c | 152 ++++++++++++++++++++++---
drivers/net/ethernet/qlogic/qed/qed_int.h | 10 ++
drivers/net/ethernet/qlogic/qed/qed_main.c | 64 ++++++++++-
drivers/net/ethernet/qlogic/qed/qed_reg_addr.h | 50 ++++++++
6 files changed, 280 insertions(+), 24 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qed/qed.h b/drivers/net/ethernet/qlogic/qed/qed.h
index 882279e..a053062 100644
--- a/drivers/net/ethernet/qlogic/qed/qed.h
+++ b/drivers/net/ethernet/qlogic/qed/qed.h
@@ -536,6 +536,7 @@ struct qed_simd_fp_handler {
enum qed_slowpath_wq_flag {
QED_SLOWPATH_MFW_TLV_REQ,
+ QED_SLOWPATH_PERIODIC_DB_REC,
};
struct qed_hwfn {
@@ -669,11 +670,12 @@ struct qed_hwfn {
struct delayed_work iov_task;
unsigned long iov_task_flags;
#endif
-
- struct z_stream_s *stream;
+ struct z_stream_s *stream;
+ bool slowpath_wq_active;
struct workqueue_struct *slowpath_wq;
struct delayed_work slowpath_task;
unsigned long slowpath_task_flags;
+ u32 periodic_db_rec_count;
};
struct pci_params {
@@ -914,6 +916,12 @@ void qed_set_fw_mac_addr(__le16 *fw_msb,
#define QED_LEADING_HWFN(dev) (&dev->hwfns[0])
+/* doorbell recovery mechanism */
+void qed_db_recovery_dp(struct qed_hwfn *p_hwfn);
+void qed_db_recovery_execute(struct qed_hwfn *p_hwfn,
+ enum qed_db_rec_exec db_exec);
+bool qed_edpm_enabled(struct qed_hwfn *p_hwfn);
+
/* Other Linux specific common definitions */
#define DP_NAME(cdev) ((cdev)->name)
@@ -948,4 +956,6 @@ int qed_mfw_fill_tlv_data(struct qed_hwfn *hwfn,
union qed_mfw_tlv_data *tlv_data);
void qed_hw_info_set_offload_tc(struct qed_hw_info *p_info, u8 tc);
+
+void qed_periodic_db_rec_start(struct qed_hwfn *p_hwfn);
#endif /* _QED_H */
diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c
index a63f87f..0172d90 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dev.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c
@@ -1759,6 +1759,14 @@ enum QED_ROCE_EDPM_MODE {
QED_ROCE_EDPM_MODE_DISABLE = 2,
};
+bool qed_edpm_enabled(struct qed_hwfn *p_hwfn)
+{
+ if (p_hwfn->dcbx_no_edpm || p_hwfn->db_bar_no_edpm)
+ return false;
+
+ return true;
+}
+
static int
qed_hw_init_pf_doorbell_bar(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
{
@@ -1828,13 +1836,13 @@ enum QED_ROCE_EDPM_MODE {
p_hwfn->wid_count = (u16) n_cpus;
DP_INFO(p_hwfn,
- "doorbell bar: normal_region_size=%d, pwm_region_size=%d, dpi_size=%d, dpi_count=%d, roce_edpm=%s\n",
+ "doorbell bar: normal_region_size=%d, pwm_region_size=%d, dpi_size=%d, dpi_count=%d, roce_edpm=%s, page_size=%lu\n",
norm_regsize,
pwm_regsize,
p_hwfn->dpi_size,
p_hwfn->dpi_count,
- ((p_hwfn->dcbx_no_edpm) || (p_hwfn->db_bar_no_edpm)) ?
- "disabled" : "enabled");
+ (!qed_edpm_enabled(p_hwfn)) ?
+ "disabled" : "enabled", PAGE_SIZE);
if (rc) {
DP_ERR(p_hwfn,
diff --git a/drivers/net/ethernet/qlogic/qed/qed_int.c b/drivers/net/ethernet/qlogic/qed/qed_int.c
index af3a28e..0fe44a6 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_int.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_int.c
@@ -361,29 +361,147 @@ static int qed_pglub_rbc_attn_cb(struct qed_hwfn *p_hwfn)
return 0;
}
-#define QED_DORQ_ATTENTION_REASON_MASK (0xfffff)
-#define QED_DORQ_ATTENTION_OPAQUE_MASK (0xffff)
-#define QED_DORQ_ATTENTION_SIZE_MASK (0x7f)
-#define QED_DORQ_ATTENTION_SIZE_SHIFT (16)
+#define QED_DORQ_ATTENTION_REASON_MASK (0xfffff)
+#define QED_DORQ_ATTENTION_OPAQUE_MASK (0xffff)
+#define QED_DORQ_ATTENTION_OPAQUE_SHIFT (0x0)
+#define QED_DORQ_ATTENTION_SIZE_MASK (0x7f)
+#define QED_DORQ_ATTENTION_SIZE_SHIFT (16)
+
+#define QED_DB_REC_COUNT 1000
+#define QED_DB_REC_INTERVAL 100
+
+static int qed_db_rec_flush_queue(struct qed_hwfn *p_hwfn,
+ struct qed_ptt *p_ptt)
+{
+ u32 count = QED_DB_REC_COUNT;
+ u32 usage = 1;
+
+ /* wait for usage to zero or count to run out. This is necessary since
+ * EDPM doorbell transactions can take multiple 64b cycles, and as such
+ * can "split" over the pci. Possibly, the doorbell drop can happen with
+ * half an EDPM in the queue and other half dropped. Another EDPM
+ * doorbell to the same address (from doorbell recovery mechanism or
+ * from the doorbelling entity) could have first half dropped and second
+ * half interpreted as continuation of the first. To prevent such
+ * malformed doorbells from reaching the device, flush the queue before
+ * releasing the overflow sticky indication.
+ */
+ while (count-- && usage) {
+ usage = qed_rd(p_hwfn, p_ptt, DORQ_REG_PF_USAGE_CNT);
+ udelay(QED_DB_REC_INTERVAL);
+ }
+
+ /* should have been depleted by now */
+ if (usage) {
+ DP_NOTICE(p_hwfn->cdev,
+ "DB recovery: doorbell usage failed to zero after %d usec. usage was %x\n",
+ QED_DB_REC_INTERVAL * QED_DB_REC_COUNT, usage);
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+int qed_db_rec_handler(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
+{
+ u32 overflow;
+ int rc;
+
+ overflow = qed_rd(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY);
+ DP_NOTICE(p_hwfn, "PF Overflow sticky 0x%x\n", overflow);
+ if (!overflow) {
+ qed_db_recovery_execute(p_hwfn, DB_REC_ONCE);
+ return 0;
+ }
+
+ if (qed_edpm_enabled(p_hwfn)) {
+ rc = qed_db_rec_flush_queue(p_hwfn, p_ptt);
+ if (rc)
+ return rc;
+ }
+
+ /* Flush any pending (e)dpm as they may never arrive */
+ qed_wr(p_hwfn, p_ptt, DORQ_REG_DPM_FORCE_ABORT, 0x1);
+
+ /* Release overflow sticky indication (stop silently dropping everything) */
+ qed_wr(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY, 0x0);
+
+ /* Repeat all last doorbells (doorbell drop recovery) */
+ qed_db_recovery_execute(p_hwfn, DB_REC_REAL_DEAL);
+
+ return 0;
+}
+
static int qed_dorq_attn_cb(struct qed_hwfn *p_hwfn)
{
- u32 reason;
+ u32 int_sts, first_drop_reason, details, address, all_drops_reason;
+ struct qed_ptt *p_ptt = p_hwfn->p_dpc_ptt;
+ int rc;
- reason = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, DORQ_REG_DB_DROP_REASON) &
- QED_DORQ_ATTENTION_REASON_MASK;
- if (reason) {
- u32 details = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
- DORQ_REG_DB_DROP_DETAILS);
+ int_sts = qed_rd(p_hwfn, p_ptt, DORQ_REG_INT_STS);
+ DP_NOTICE(p_hwfn->cdev, "DORQ attention. int_sts was %x\n", int_sts);
- DP_INFO(p_hwfn->cdev,
- "DORQ db_drop: address 0x%08x Opaque FID 0x%04x Size [bytes] 0x%08x Reason: 0x%08x\n",
- qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
- DORQ_REG_DB_DROP_DETAILS_ADDRESS),
- (u16)(details & QED_DORQ_ATTENTION_OPAQUE_MASK),
- GET_FIELD(details, QED_DORQ_ATTENTION_SIZE) * 4,
- reason);
+ /* int_sts may be zero since all PFs were interrupted for doorbell
+ * overflow but another one already handled it. Can abort here. If
+ * This PF also requires overflow recovery we will be interrupted again.
+ * The masked almost full indication may also be set. Ignoring.
+ */
+ if (!(int_sts & ~DORQ_REG_INT_STS_DORQ_FIFO_AFULL))
+ return 0;
+
+ /* check if db_drop or overflow happened */
+ if (int_sts & (DORQ_REG_INT_STS_DB_DROP |
+ DORQ_REG_INT_STS_DORQ_FIFO_OVFL_ERR)) {
+ /* Obtain data about db drop/overflow */
+ first_drop_reason = qed_rd(p_hwfn, p_ptt,
+ DORQ_REG_DB_DROP_REASON) &
+ QED_DORQ_ATTENTION_REASON_MASK;
+ details = qed_rd(p_hwfn, p_ptt, DORQ_REG_DB_DROP_DETAILS);
+ address = qed_rd(p_hwfn, p_ptt,
+ DORQ_REG_DB_DROP_DETAILS_ADDRESS);
+ all_drops_reason = qed_rd(p_hwfn, p_ptt,
+ DORQ_REG_DB_DROP_DETAILS_REASON);
+
+ /* Log info */
+ DP_NOTICE(p_hwfn->cdev,
+ "Doorbell drop occurred\n"
+ "Address\t\t0x%08x\t(second BAR address)\n"
+ "FID\t\t0x%04x\t\t(Opaque FID)\n"
+ "Size\t\t0x%04x\t\t(in bytes)\n"
+ "1st drop reason\t0x%08x\t(details on first drop since last handling)\n"
+ "Sticky reasons\t0x%08x\t(all drop reasons since last handling)\n",
+ address,
+ GET_FIELD(details, QED_DORQ_ATTENTION_OPAQUE),
+ GET_FIELD(details, QED_DORQ_ATTENTION_SIZE) * 4,
+ first_drop_reason, all_drops_reason);
+
+ rc = qed_db_rec_handler(p_hwfn, p_ptt);
+ qed_periodic_db_rec_start(p_hwfn);
+ if (rc)
+ return rc;
+
+ /* Clear the doorbell drop details and prepare for next drop */
+ qed_wr(p_hwfn, p_ptt, DORQ_REG_DB_DROP_DETAILS_REL, 0);
+
+ /* Mark interrupt as handled (note: even if drop was due to a different
+ * reason than overflow we mark as handled)
+ */
+ qed_wr(p_hwfn,
+ p_ptt,
+ DORQ_REG_INT_STS_WR,
+ DORQ_REG_INT_STS_DB_DROP |
+ DORQ_REG_INT_STS_DORQ_FIFO_OVFL_ERR);
+
+ /* If there are no indications other than drop indications, success */
+ if ((int_sts & ~(DORQ_REG_INT_STS_DB_DROP |
+ DORQ_REG_INT_STS_DORQ_FIFO_OVFL_ERR |
+ DORQ_REG_INT_STS_DORQ_FIFO_AFULL)) == 0)
+ return 0;
}
+ /* Some other indication was present - non recoverable */
+ DP_INFO(p_hwfn, "DORQ fatal attention\n");
+
return -EINVAL;
}
diff --git a/drivers/net/ethernet/qlogic/qed/qed_int.h b/drivers/net/ethernet/qlogic/qed/qed_int.h
index 54b4ee0..d81a62e 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_int.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_int.h
@@ -190,6 +190,16 @@ void qed_int_get_num_sbs(struct qed_hwfn *p_hwfn,
*/
void qed_int_disable_post_isr_release(struct qed_dev *cdev);
+/**
+ * @brief - Doorbell Recovery handler.
+ * Run DB_REAL_DEAL doorbell recovery in case of PF overflow
+ * (and flush DORQ if needed), otherwise run DB_REC_ONCE.
+ *
+ * @param p_hwfn
+ * @param p_ptt
+ */
+int qed_db_rec_handler(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
+
#define QED_CAU_DEF_RX_TIMER_RES 0
#define QED_CAU_DEF_TX_TIMER_RES 0
diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c
index 75d217a..f2c50ef 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
@@ -965,9 +965,47 @@ static void qed_update_pf_params(struct qed_dev *cdev,
}
}
+#define QED_PERIODIC_DB_REC_COUNT 100
+#define QED_PERIODIC_DB_REC_INTERVAL_MS 100
+#define QED_PERIODIC_DB_REC_INTERVAL \
+ msecs_to_jiffies(QED_PERIODIC_DB_REC_INTERVAL_MS)
+#define QED_PERIODIC_DB_REC_WAIT_COUNT 10
+#define QED_PERIODIC_DB_REC_WAIT_INTERVAL \
+ (QED_PERIODIC_DB_REC_INTERVAL_MS / QED_PERIODIC_DB_REC_WAIT_COUNT)
+
+static int qed_slowpath_delayed_work(struct qed_hwfn *hwfn,
+ enum qed_slowpath_wq_flag wq_flag,
+ unsigned long delay)
+{
+ if (!hwfn->slowpath_wq_active)
+ return -EINVAL;
+
+ /* Memory barrier for setting atomic bit */
+ smp_mb__before_atomic();
+ set_bit(wq_flag, &hwfn->slowpath_task_flags);
+ smp_mb__after_atomic();
+ queue_delayed_work(hwfn->slowpath_wq, &hwfn->slowpath_task, delay);
+
+ return 0;
+}
+
+void qed_periodic_db_rec_start(struct qed_hwfn *p_hwfn)
+{
+ /* Reset periodic Doorbell Recovery counter */
+ p_hwfn->periodic_db_rec_count = QED_PERIODIC_DB_REC_COUNT;
+
+ /* Don't schedule periodic Doorbell Recovery if already scheduled */
+ if (test_bit(QED_SLOWPATH_PERIODIC_DB_REC,
+ &p_hwfn->slowpath_task_flags))
+ return;
+
+ qed_slowpath_delayed_work(p_hwfn, QED_SLOWPATH_PERIODIC_DB_REC,
+ QED_PERIODIC_DB_REC_INTERVAL);
+}
+
static void qed_slowpath_wq_stop(struct qed_dev *cdev)
{
- int i;
+ int i, sleep_count = QED_PERIODIC_DB_REC_WAIT_COUNT;
if (IS_VF(cdev))
return;
@@ -976,6 +1014,15 @@ static void qed_slowpath_wq_stop(struct qed_dev *cdev)
if (!cdev->hwfns[i].slowpath_wq)
continue;
+ /* Stop queuing new delayed works */
+ cdev->hwfns[i].slowpath_wq_active = false;
+
+ /* Wait until the last periodic doorbell recovery is executed */
+ while (test_bit(QED_SLOWPATH_PERIODIC_DB_REC,
+ &cdev->hwfns[i].slowpath_task_flags) &&
+ sleep_count--)
+ msleep(QED_PERIODIC_DB_REC_WAIT_INTERVAL);
+
flush_workqueue(cdev->hwfns[i].slowpath_wq);
destroy_workqueue(cdev->hwfns[i].slowpath_wq);
}
@@ -988,7 +1035,10 @@ static void qed_slowpath_task(struct work_struct *work)
struct qed_ptt *ptt = qed_ptt_acquire(hwfn);
if (!ptt) {
- queue_delayed_work(hwfn->slowpath_wq, &hwfn->slowpath_task, 0);
+ if (hwfn->slowpath_wq_active)
+ queue_delayed_work(hwfn->slowpath_wq,
+ &hwfn->slowpath_task, 0);
+
return;
}
@@ -996,6 +1046,15 @@ static void qed_slowpath_task(struct work_struct *work)
&hwfn->slowpath_task_flags))
qed_mfw_process_tlv_req(hwfn, ptt);
+ if (test_and_clear_bit(QED_SLOWPATH_PERIODIC_DB_REC,
+ &hwfn->slowpath_task_flags)) {
+ qed_db_rec_handler(hwfn, ptt);
+ if (hwfn->periodic_db_rec_count--)
+ qed_slowpath_delayed_work(hwfn,
+ QED_SLOWPATH_PERIODIC_DB_REC,
+ QED_PERIODIC_DB_REC_INTERVAL);
+ }
+
qed_ptt_release(hwfn, ptt);
}
@@ -1022,6 +1081,7 @@ static int qed_slowpath_wq_start(struct qed_dev *cdev)
}
INIT_DELAYED_WORK(&hwfn->slowpath_task, qed_slowpath_task);
+ hwfn->slowpath_wq_active = true;
}
return 0;
diff --git a/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h b/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
index 2440970..8939ed6 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
@@ -1243,6 +1243,56 @@
0x1701534UL
#define TSEM_REG_DBG_FORCE_FRAME \
0x1701538UL
+#define DORQ_REG_PF_USAGE_CNT \
+ 0x1009c0UL
+#define DORQ_REG_PF_OVFL_STICKY \
+ 0x1009d0UL
+#define DORQ_REG_DPM_FORCE_ABORT \
+ 0x1009d8UL
+#define DORQ_REG_INT_STS \
+ 0x100180UL
+#define DORQ_REG_INT_STS_ADDRESS_ERROR \
+ (0x1UL << 0)
+#define DORQ_REG_INT_STS_WR \
+ 0x100188UL
+#define DORQ_REG_DB_DROP_DETAILS_REL \
+ 0x100a28UL
+#define DORQ_REG_INT_STS_ADDRESS_ERROR_SHIFT \
+ 0
+#define DORQ_REG_INT_STS_DB_DROP \
+ (0x1UL << 1)
+#define DORQ_REG_INT_STS_DB_DROP_SHIFT \
+ 1
+#define DORQ_REG_INT_STS_DORQ_FIFO_OVFL_ERR \
+ (0x1UL << 2)
+#define DORQ_REG_INT_STS_DORQ_FIFO_OVFL_ERR_SHIFT \
+ 2
+#define DORQ_REG_INT_STS_DORQ_FIFO_AFULL\
+ (0x1UL << 3)
+#define DORQ_REG_INT_STS_DORQ_FIFO_AFULL_SHIFT \
+ 3
+#define DORQ_REG_INT_STS_CFC_BYP_VALIDATION_ERR \
+ (0x1UL << 4)
+#define DORQ_REG_INT_STS_CFC_BYP_VALIDATION_ERR_SHIFT \
+ 4
+#define DORQ_REG_INT_STS_CFC_LD_RESP_ERR \
+ (0x1UL << 5)
+#define DORQ_REG_INT_STS_CFC_LD_RESP_ERR_SHIFT \
+ 5
+#define DORQ_REG_INT_STS_XCM_DONE_CNT_ERR \
+ (0x1UL << 6)
+#define DORQ_REG_INT_STS_XCM_DONE_CNT_ERR_SHIFT \
+ 6
+#define DORQ_REG_INT_STS_CFC_LD_REQ_FIFO_OVFL_ERR \
+ (0x1UL << 7)
+#define DORQ_REG_INT_STS_CFC_LD_REQ_FIFO_OVFL_ERR_SHIFT \
+ 7
+#define DORQ_REG_INT_STS_CFC_LD_REQ_FIFO_UNDER_ERR \
+ (0x1UL << 8)
+#define DORQ_REG_INT_STS_CFC_LD_REQ_FIFO_UNDER_ERR_SHIFT \
+ 8
+#define DORQ_REG_DB_DROP_DETAILS_REASON \
+ 0x100a20UL
#define MSEM_REG_DBG_SELECT \
0x1801528UL
#define MSEM_REG_DBG_DWORD_ENABLE \
--
1.8.3.1
^ permalink raw reply related
* [PATCH net-next v3 3/6] qed: Register slowpath queue doorbell with doorbell overflow recovery mechanism
From: Ariel Elior @ 2018-10-23 5:35 UTC (permalink / raw)
To: davem; +Cc: netdev, Ariel Elior, Michal Kalderon, Tomer Tayar
In-Reply-To: <20181023053549.5591-1-Ariel.Elior@cavium.com>
Slow path queue is a doorbelling entity. Register it with the overflow mechanism.
Signed-off-by: Ariel Elior <Ariel.Elior@cavium.com>
Signed-off-by: Michal Kalderon <Michal.Kalderon@cavium.com>
Signed-off-by: Tomer Tayar <Tomer.Tayar@cavium.com>
---
drivers/net/ethernet/qlogic/qed/qed_sp.h | 4 ++-
drivers/net/ethernet/qlogic/qed/qed_spq.c | 47 +++++++++++++++++++++++--------
2 files changed, 38 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_sp.h b/drivers/net/ethernet/qlogic/qed/qed_sp.h
index e95431f..17aa25f 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_sp.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_sp.h
@@ -224,7 +224,9 @@ struct qed_spq {
u32 comp_count;
u32 cid;
- qed_spq_async_comp_cb async_comp_cb[MAX_PROTOCOL_TYPE];
+ u32 db_addr_offset;
+ struct core_db_data db_data;
+ qed_spq_async_comp_cb async_comp_cb[MAX_PROTOCOL_TYPE];
};
/**
diff --git a/drivers/net/ethernet/qlogic/qed/qed_spq.c b/drivers/net/ethernet/qlogic/qed/qed_spq.c
index c4a6274..29039bb 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_spq.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_spq.c
@@ -254,9 +254,9 @@ static int qed_spq_hw_post(struct qed_hwfn *p_hwfn,
struct qed_spq *p_spq, struct qed_spq_entry *p_ent)
{
struct qed_chain *p_chain = &p_hwfn->p_spq->chain;
+ struct core_db_data *p_db_data = &p_spq->db_data;
u16 echo = qed_chain_get_prod_idx(p_chain);
struct slow_path_element *elem;
- struct core_db_data db;
p_ent->elem.hdr.echo = cpu_to_le16(echo);
elem = qed_chain_produce(p_chain);
@@ -268,27 +268,22 @@ static int qed_spq_hw_post(struct qed_hwfn *p_hwfn,
*elem = p_ent->elem; /* struct assignment */
/* send a doorbell on the slow hwfn session */
- memset(&db, 0, sizeof(db));
- SET_FIELD(db.params, CORE_DB_DATA_DEST, DB_DEST_XCM);
- SET_FIELD(db.params, CORE_DB_DATA_AGG_CMD, DB_AGG_CMD_SET);
- SET_FIELD(db.params, CORE_DB_DATA_AGG_VAL_SEL,
- DQ_XCM_CORE_SPQ_PROD_CMD);
- db.agg_flags = DQ_XCM_CORE_DQ_CF_CMD;
- db.spq_prod = cpu_to_le16(qed_chain_get_prod_idx(p_chain));
+ p_db_data->spq_prod = cpu_to_le16(qed_chain_get_prod_idx(p_chain));
/* make sure the SPQE is updated before the doorbell */
wmb();
- DOORBELL(p_hwfn, qed_db_addr(p_spq->cid, DQ_DEMS_LEGACY), *(u32 *)&db);
+ DOORBELL(p_hwfn, p_spq->db_addr_offset, *(u32 *)p_db_data);
/* make sure doorbell is rang */
wmb();
DP_VERBOSE(p_hwfn, QED_MSG_SPQ,
"Doorbelled [0x%08x, CID 0x%08x] with Flags: %02x agg_params: %02x, prod: %04x\n",
- qed_db_addr(p_spq->cid, DQ_DEMS_LEGACY),
- p_spq->cid, db.params, db.agg_flags,
- qed_chain_get_prod_idx(p_chain));
+ p_spq->db_addr_offset,
+ p_spq->cid,
+ p_db_data->params,
+ p_db_data->agg_flags, qed_chain_get_prod_idx(p_chain));
return 0;
}
@@ -492,8 +487,11 @@ void qed_spq_setup(struct qed_hwfn *p_hwfn)
{
struct qed_spq *p_spq = p_hwfn->p_spq;
struct qed_spq_entry *p_virt = NULL;
+ struct core_db_data *p_db_data;
+ void __iomem *db_addr;
dma_addr_t p_phys = 0;
u32 i, capacity;
+ int rc;
INIT_LIST_HEAD(&p_spq->pending);
INIT_LIST_HEAD(&p_spq->completion_pending);
@@ -530,6 +528,25 @@ void qed_spq_setup(struct qed_hwfn *p_hwfn)
/* reset the chain itself */
qed_chain_reset(&p_spq->chain);
+
+ /* Initialize the address/data of the SPQ doorbell */
+ p_spq->db_addr_offset = qed_db_addr(p_spq->cid, DQ_DEMS_LEGACY);
+ p_db_data = &p_spq->db_data;
+ memset(p_db_data, 0, sizeof(*p_db_data));
+ SET_FIELD(p_db_data->params, CORE_DB_DATA_DEST, DB_DEST_XCM);
+ SET_FIELD(p_db_data->params, CORE_DB_DATA_AGG_CMD, DB_AGG_CMD_MAX);
+ SET_FIELD(p_db_data->params, CORE_DB_DATA_AGG_VAL_SEL,
+ DQ_XCM_CORE_SPQ_PROD_CMD);
+ p_db_data->agg_flags = DQ_XCM_CORE_DQ_CF_CMD;
+
+ /* Register the SPQ doorbell with the doorbell recovery mechanism */
+ db_addr = (void __iomem *)((u8 __iomem *)p_hwfn->doorbells +
+ p_spq->db_addr_offset);
+ rc = qed_db_recovery_add(p_hwfn->cdev, db_addr, &p_spq->db_data,
+ DB_REC_WIDTH_32B, DB_REC_KERNEL);
+ if (rc)
+ DP_INFO(p_hwfn,
+ "Failed to register the SPQ doorbell with the doorbell recovery mechanism\n");
}
int qed_spq_alloc(struct qed_hwfn *p_hwfn)
@@ -577,11 +594,17 @@ int qed_spq_alloc(struct qed_hwfn *p_hwfn)
void qed_spq_free(struct qed_hwfn *p_hwfn)
{
struct qed_spq *p_spq = p_hwfn->p_spq;
+ void __iomem *db_addr;
u32 capacity;
if (!p_spq)
return;
+ /* Delete the SPQ doorbell from the doorbell recovery mechanism */
+ db_addr = (void __iomem *)((u8 __iomem *)p_hwfn->doorbells +
+ p_spq->db_addr_offset);
+ qed_db_recovery_del(p_hwfn->cdev, db_addr, &p_spq->db_data);
+
if (p_spq->p_virt) {
capacity = qed_chain_get_capacity(&p_spq->chain);
dma_free_coherent(&p_hwfn->cdev->pdev->dev,
--
1.8.3.1
^ permalink raw reply related
* [PATCH net-next v3 4/6] qed: Register light L2 queues with doorbell overflow recovery mechanism
From: Ariel Elior @ 2018-10-23 5:35 UTC (permalink / raw)
To: davem; +Cc: netdev, Ariel Elior, Michal Kalderon, Tomer Tayar
In-Reply-To: <20181023053549.5591-1-Ariel.Elior@cavium.com>
Light L2 queues are doorbelling entities. Modify the implementation
to keep the doorbell data necessary for doorbelling in well known
location instead of recomputing every time. Register the LL2 queue
with doorbell recovery mechanism.
Signed-off-by: Ariel Elior <Ariel.Elior@cavium.com>
Signed-off-by: Michal Kalderon <Michal.Kalderon@cavium.com>
Signed-off-by: Tomer Tayar <Tomer.Tayar@cavium.com>
---
drivers/net/ethernet/qlogic/qed/qed_ll2.c | 30 ++++++++++++++++++++----------
drivers/net/ethernet/qlogic/qed/qed_ll2.h | 1 +
2 files changed, 21 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
index aa63338..504c8f7 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
@@ -1085,7 +1085,14 @@ static int qed_sp_ll2_tx_queue_start(struct qed_hwfn *p_hwfn,
p_ramrod->gsi_offload_flag = p_ll2_conn->input.gsi_enable;
- return qed_spq_post(p_hwfn, p_ent, NULL);
+ rc = qed_spq_post(p_hwfn, p_ent, NULL);
+ if (rc)
+ return rc;
+
+ rc = qed_db_recovery_add(p_hwfn->cdev, p_tx->doorbell_addr,
+ &p_tx->db_msg, DB_REC_WIDTH_32B,
+ DB_REC_KERNEL);
+ return rc;
}
static int qed_sp_ll2_rx_queue_stop(struct qed_hwfn *p_hwfn,
@@ -1119,9 +1126,11 @@ static int qed_sp_ll2_rx_queue_stop(struct qed_hwfn *p_hwfn,
static int qed_sp_ll2_tx_queue_stop(struct qed_hwfn *p_hwfn,
struct qed_ll2_info *p_ll2_conn)
{
+ struct qed_ll2_tx_queue *p_tx = &p_ll2_conn->tx_queue;
struct qed_spq_entry *p_ent = NULL;
struct qed_sp_init_data init_data;
int rc = -EINVAL;
+ qed_db_recovery_del(p_hwfn->cdev, p_tx->doorbell_addr, &p_tx->db_msg);
/* Get SPQ entry */
memset(&init_data, 0, sizeof(init_data));
@@ -1542,6 +1551,13 @@ int qed_ll2_establish_connection(void *cxt, u8 connection_handle)
p_tx->doorbell_addr = (u8 __iomem *)p_hwfn->doorbells +
qed_db_addr(p_ll2_conn->cid,
DQ_DEMS_LEGACY);
+ /* prepare db data */
+ SET_FIELD(p_tx->db_msg.params, CORE_DB_DATA_DEST, DB_DEST_XCM);
+ SET_FIELD(p_tx->db_msg.params, CORE_DB_DATA_AGG_CMD, DB_AGG_CMD_SET);
+ SET_FIELD(p_tx->db_msg.params, CORE_DB_DATA_AGG_VAL_SEL,
+ DQ_XCM_CORE_TX_BD_PROD_CMD);
+ p_tx->db_msg.agg_flags = DQ_XCM_CORE_DQ_CF_CMD;
+
rc = qed_ll2_establish_connection_rx(p_hwfn, p_ll2_conn);
if (rc)
@@ -1780,7 +1796,6 @@ static void qed_ll2_tx_packet_notify(struct qed_hwfn *p_hwfn,
bool b_notify = p_ll2_conn->tx_queue.cur_send_packet->notify_fw;
struct qed_ll2_tx_queue *p_tx = &p_ll2_conn->tx_queue;
struct qed_ll2_tx_packet *p_pkt = NULL;
- struct core_db_data db_msg = { 0, 0, 0 };
u16 bd_prod;
/* If there are missing BDs, don't do anything now */
@@ -1809,24 +1824,19 @@ static void qed_ll2_tx_packet_notify(struct qed_hwfn *p_hwfn,
list_move_tail(&p_pkt->list_entry, &p_tx->active_descq);
}
- SET_FIELD(db_msg.params, CORE_DB_DATA_DEST, DB_DEST_XCM);
- SET_FIELD(db_msg.params, CORE_DB_DATA_AGG_CMD, DB_AGG_CMD_SET);
- SET_FIELD(db_msg.params, CORE_DB_DATA_AGG_VAL_SEL,
- DQ_XCM_CORE_TX_BD_PROD_CMD);
- db_msg.agg_flags = DQ_XCM_CORE_DQ_CF_CMD;
- db_msg.spq_prod = cpu_to_le16(bd_prod);
+ p_tx->db_msg.spq_prod = cpu_to_le16(bd_prod);
/* Make sure the BDs data is updated before ringing the doorbell */
wmb();
- DIRECT_REG_WR(p_tx->doorbell_addr, *((u32 *)&db_msg));
+ DIRECT_REG_WR(p_tx->doorbell_addr, *((u32 *)&p_tx->db_msg));
DP_VERBOSE(p_hwfn,
(NETIF_MSG_TX_QUEUED | QED_MSG_LL2),
"LL2 [q 0x%02x cid 0x%08x type 0x%08x] Doorbelled [producer 0x%04x]\n",
p_ll2_conn->queue_id,
p_ll2_conn->cid,
- p_ll2_conn->input.conn_type, db_msg.spq_prod);
+ p_ll2_conn->input.conn_type, p_tx->db_msg.spq_prod);
}
int qed_ll2_prepare_tx_packet(void *cxt,
diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.h b/drivers/net/ethernet/qlogic/qed/qed_ll2.h
index 1a5c1ae..5f01fbd 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_ll2.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.h
@@ -103,6 +103,7 @@ struct qed_ll2_tx_queue {
struct qed_ll2_tx_packet cur_completing_packet;
u16 cur_completing_bd_idx;
void __iomem *doorbell_addr;
+ struct core_db_data db_msg;
u16 bds_idx;
u16 cur_send_frag_num;
u16 cur_completing_frag_num;
--
1.8.3.1
^ permalink raw reply related
* [PATCH net-next v3 6/6] qede: Register l2 queues with doorbell overflow recovery mechanism
From: Ariel Elior @ 2018-10-23 5:35 UTC (permalink / raw)
To: davem; +Cc: netdev, Ariel Elior, Michal Kalderon, Tomer Tayar
In-Reply-To: <20181023053549.5591-1-Ariel.Elior@cavium.com>
All L2 queues funnel through this flow, so this would cover the
regular RSS queues, as well queues created for VFs, mqos queues,
xdp queues, etc.
Signed-off-by: Ariel Elior <Ariel.Elior@cavium.com>
Signed-off-by: Michal Kalderon <Michal.Kalderon@cavium.com>
Signed-off-by: Tomer Tayar <Tomer.Tayar@cavium.com>
---
drivers/net/ethernet/qlogic/qede/qede_main.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c
index 46d0f2e..1c4cea8 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
@@ -1774,6 +1774,10 @@ static int qede_drain_txq(struct qede_dev *edev,
static int qede_stop_txq(struct qede_dev *edev,
struct qede_tx_queue *txq, int rss_id)
{
+ /* delete doorbell from doorbell recovery mechanism */
+ edev->ops->common->db_recovery_del(edev->cdev, txq->doorbell_addr,
+ &txq->tx_db);
+
return edev->ops->q_tx_stop(edev->cdev, rss_id, txq->handle);
}
@@ -1910,6 +1914,11 @@ static int qede_start_txq(struct qede_dev *edev,
DQ_XCM_ETH_TX_BD_PROD_CMD);
txq->tx_db.data.agg_flags = DQ_XCM_ETH_DQ_CF_CMD;
+ /* register doorbell with doorbell recovery mechanism */
+ rc = edev->ops->common->db_recovery_add(edev->cdev, txq->doorbell_addr,
+ &txq->tx_db, DB_REC_WIDTH_32B,
+ DB_REC_KERNEL);
+
return rc;
}
--
1.8.3.1
^ permalink raw reply related
* [PATCH net-next v3 5/6] qed: Expose the doorbell overflow recovery mechanism to the protocol drivers
From: Ariel Elior @ 2018-10-23 5:35 UTC (permalink / raw)
To: davem; +Cc: netdev, Ariel Elior, Michal Kalderon, Tomer Tayar
In-Reply-To: <20181023053549.5591-1-Ariel.Elior@cavium.com>
Most of the doorbelling entities are outside of the core module.
L2 queues, Roce queues, iscsi and fcoe all need to register.
Make the APIs available for these drivers.
Signed-off-by: Ariel Elior <Ariel.Elior@cavium.com>
Signed-off-by: Michal Kalderon <Michal.Kalderon@cavium.com>
Signed-off-by: Tomer Tayar <Tomer.Tayar@cavium.com>
---
drivers/net/ethernet/qlogic/qed/qed_main.c | 2 ++
include/linux/qed/qed_if.h | 27 +++++++++++++++++++++++++++
2 files changed, 29 insertions(+)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c
index f2c50ef..a0b761d 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
@@ -2238,6 +2238,8 @@ static int qed_read_module_eeprom(struct qed_dev *cdev, char *buf,
.update_mac = &qed_update_mac,
.update_mtu = &qed_update_mtu,
.update_wol = &qed_update_wol,
+ .db_recovery_add = &qed_db_recovery_add,
+ .db_recovery_del = &qed_db_recovery_del,
.read_module_eeprom = &qed_read_module_eeprom,
};
diff --git a/include/linux/qed/qed_if.h b/include/linux/qed/qed_if.h
index 41382e7..8b2b005 100644
--- a/include/linux/qed/qed_if.h
+++ b/include/linux/qed/qed_if.h
@@ -1009,6 +1009,33 @@ struct qed_common_ops {
*/
int (*set_led)(struct qed_dev *cdev,
enum qed_led_mode mode);
+/**
+ * @brief db_recovery_add - add doorbell information to the doorbell
+ * recovery mechanism.
+ *
+ * @param cdev
+ * @param db_addr - doorbell address
+ * @param db_data - address of where db_data is stored
+ * @param db_is_32b - doorbell is 32b pr 64b
+ * @param db_is_user - doorbell recovery addresses are user or kernel space
+ */
+ int (*db_recovery_add)(struct qed_dev *cdev,
+ void __iomem *db_addr,
+ void *db_data,
+ enum qed_db_rec_width db_width,
+ enum qed_db_rec_space db_space);
+
+/**
+ * @brief db_recovery_del - remove doorbell information from the doorbell
+ * recovery mechanism. db_data serves as key (db_addr is not unique).
+ *
+ * @param cdev
+ * @param db_addr - doorbell address
+ * @param db_data - address where db_data is stored. Serves as key for the
+ * entry to delete.
+ */
+ int (*db_recovery_del)(struct qed_dev *cdev,
+ void __iomem *db_addr, void *db_data);
/**
* @brief update_drv_state - API to inform the change in the driver state.
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH net-next 0/6 v2] qed*: Doorbell overflow recovery
From: David Miller @ 2018-10-23 5:50 UTC (permalink / raw)
To: Ariel.Elior; +Cc: netdev, Michal.Kalderon, Tomer.Tayar
In-Reply-To: <20181023053549.5591-1-Ariel.Elior@cavium.com>
From: Ariel Elior <Ariel.Elior@cavium.com>
Date: Tue, 23 Oct 2018 08:35:43 +0300
> Please consider applying to net-next.
Sorry, net-next is closed.
^ permalink raw reply
* Re: [PATCH] libertas: remove set but not used variable 'int_type'
From: Lubomir Rintel @ 2018-10-23 14:23 UTC (permalink / raw)
To: zhong jiang, kvalo
Cc: davem, libertas-dev, linux-wireless, netdev, linux-kernel
In-Reply-To: <1540265568-58721-1-git-send-email-zhongjiang@huawei.com>
On Tue, 2018-10-23 at 11:32 +0800, zhong jiang wrote:
> int_type is not used after setting its value. It is safe to remove
> the unused variable.
Hi. I believe your colleague has sent an equivalent patch a few days
ago in <1539569795-176889-1-git-send-email-yuehaibing@huawei.com>:
https://lore.kernel.org/linux-wireless/1539569795-176889-1-git-send-email-yuehaibing@huawei.com/
Cheers,
Lubo
>
> Signed-off-by: zhong jiang <zhongjiang@huawei.com>
> ---
> drivers/net/wireless/marvell/libertas/if_spi.c | 4 +---
> 1 file changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/drivers/net/wireless/marvell/libertas/if_spi.c
> b/drivers/net/wireless/marvell/libertas/if_spi.c
> index 504d6e0..7c3224b 100644
> --- a/drivers/net/wireless/marvell/libertas/if_spi.c
> +++ b/drivers/net/wireless/marvell/libertas/if_spi.c
> @@ -796,15 +796,13 @@ static void if_spi_h2c(struct if_spi_card
> *card,
> {
> struct lbs_private *priv = card->priv;
> int err = 0;
> - u16 int_type, port_reg;
> + u16 port_reg;
>
> switch (type) {
> case MVMS_DAT:
> - int_type = IF_SPI_CIC_TX_DOWNLOAD_OVER;
> port_reg = IF_SPI_DATA_RDWRPORT_REG;
> break;
> case MVMS_CMD:
> - int_type = IF_SPI_CIC_CMD_DOWNLOAD_OVER;
> port_reg = IF_SPI_CMD_RDWRPORT_REG;
> break;
> default:
^ permalink raw reply
* Re: [PATCH] libertas: remove set but not used variable 'int_type'
From: Lubomir Rintel @ 2018-10-23 14:25 UTC (permalink / raw)
To: YueHaibing, Kalle Valo
Cc: libertas-dev-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
kernel-janitors-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1539569795-176889-1-git-send-email-yuehaibing-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
On Mon, 2018-10-15 at 02:16 +0000, YueHaibing wrote:
> Fixes gcc '-Wunused-but-set-variable' warning:
>
> drivers/net/wireless/marvell/libertas/if_spi.c: In function
> 'if_spi_h2c':
> drivers/net/wireless/marvell/libertas/if_spi.c:799:6: warning:
> variable 'int_type' set but not used [-Wunused-but-set-variable]
>
> It never used since introduction in
> commit d2b21f191753 ("libertas: if_spi, driver for libertas GSPI
> devices")
>
> Signed-off-by: YueHaibing <yuehaibing-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
Thanks.
Tested-by: Lubomir Rintel <lkundrak-NGH9Lh4a5iE@public.gmane.org>
> ---
> drivers/net/wireless/marvell/libertas/if_spi.c | 4 +---
> 1 file changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/drivers/net/wireless/marvell/libertas/if_spi.c
> b/drivers/net/wireless/marvell/libertas/if_spi.c
> index 504d6e0..7c3224b 100644
> --- a/drivers/net/wireless/marvell/libertas/if_spi.c
> +++ b/drivers/net/wireless/marvell/libertas/if_spi.c
> @@ -796,15 +796,13 @@ static void if_spi_h2c(struct if_spi_card
> *card,
> {
> struct lbs_private *priv = card->priv;
> int err = 0;
> - u16 int_type, port_reg;
> + u16 port_reg;
>
> switch (type) {
> case MVMS_DAT:
> - int_type = IF_SPI_CIC_TX_DOWNLOAD_OVER;
> port_reg = IF_SPI_DATA_RDWRPORT_REG;
> break;
> case MVMS_CMD:
> - int_type = IF_SPI_CIC_CMD_DOWNLOAD_OVER;
> port_reg = IF_SPI_CMD_RDWRPORT_REG;
> break;
> default:
>
^ permalink raw reply
* Re: [PATCH] libertas: remove set but not used variable 'int_type'
From: zhong jiang @ 2018-10-23 14:28 UTC (permalink / raw)
To: Lubomir Rintel
Cc: kvalo, davem, libertas-dev, linux-wireless, netdev, linux-kernel
In-Reply-To: <25ed3d0b71eb34e121f2d7a8d936665d7720270f.camel@v3.sk>
On 2018/10/23 22:23, Lubomir Rintel wrote:
> On Tue, 2018-10-23 at 11:32 +0800, zhong jiang wrote:
>> int_type is not used after setting its value. It is safe to remove
>> the unused variable.
> Hi. I believe your colleague has sent an equivalent patch a few days
> ago in <1539569795-176889-1-git-send-email-yuehaibing@huawei.com>:
>
> https://lore.kernel.org/linux-wireless/1539569795-176889-1-git-send-email-yuehaibing@huawei.com/
I miss that. Thanks, please ignore the patch.
Sincerely,
zhong jiang
> Cheers,
> Lubo
>
>> Signed-off-by: zhong jiang <zhongjiang@huawei.com>
>> ---
>> drivers/net/wireless/marvell/libertas/if_spi.c | 4 +---
>> 1 file changed, 1 insertion(+), 3 deletions(-)
>>
>> diff --git a/drivers/net/wireless/marvell/libertas/if_spi.c
>> b/drivers/net/wireless/marvell/libertas/if_spi.c
>> index 504d6e0..7c3224b 100644
>> --- a/drivers/net/wireless/marvell/libertas/if_spi.c
>> +++ b/drivers/net/wireless/marvell/libertas/if_spi.c
>> @@ -796,15 +796,13 @@ static void if_spi_h2c(struct if_spi_card
>> *card,
>> {
>> struct lbs_private *priv = card->priv;
>> int err = 0;
>> - u16 int_type, port_reg;
>> + u16 port_reg;
>>
>> switch (type) {
>> case MVMS_DAT:
>> - int_type = IF_SPI_CIC_TX_DOWNLOAD_OVER;
>> port_reg = IF_SPI_DATA_RDWRPORT_REG;
>> break;
>> case MVMS_CMD:
>> - int_type = IF_SPI_CIC_CMD_DOWNLOAD_OVER;
>> port_reg = IF_SPI_CMD_RDWRPORT_REG;
>> break;
>> default:
>
> .
>
^ permalink raw reply
* KASAN: use-after-free Write in hci_sock_release
From: syzbot @ 2018-10-23 14:38 UTC (permalink / raw)
To: davem, johan.hedberg, linux-bluetooth, linux-kernel, marcel,
netdev, syzkaller-bugs
Hello,
syzbot found the following crash on:
HEAD commit: 8c60c36d0b8c Add linux-next specific files for 20181019
git tree: linux-next
console output: https://syzkaller.appspot.com/x/log.txt?x=163a6499400000
kernel config: https://syzkaller.appspot.com/x/.config?x=8b6d7c4c81535e89
dashboard link: https://syzkaller.appspot.com/bug?extid=b364ed862aa07c74bc62
compiler: gcc (GCC) 8.0.1 20180413 (experimental)
Unfortunately, I don't have any reproducer for this crash yet.
IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+b364ed862aa07c74bc62@syzkaller.appspotmail.com
F2FS-fs (loop5): Can't find valid F2FS filesystem in 1th superblock
F2FS-fs (loop5): Magic Mismatch, valid(0xf2f52010) - read(0x0)
F2FS-fs (loop5): Can't find valid F2FS filesystem in 2th superblock
==================================================================
BUG: KASAN: use-after-free in atomic_dec
include/asm-generic/atomic-instrumented.h:127 [inline]
BUG: KASAN: use-after-free in hci_sock_release+0x14f/0x3b0
net/bluetooth/hci_sock.c:873
Write of size 4 at addr ffff880182f492a0 by task syz-executor0/7470
CPU: 1 PID: 7470 Comm: syz-executor0 Not tainted 4.19.0-rc8-next-20181019+
#98
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
Google 01/01/2011
Call Trace:
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0x244/0x39d lib/dump_stack.c:113
print_address_description.cold.7+0x9/0x1ff mm/kasan/report.c:256
kasan_report_error mm/kasan/report.c:354 [inline]
kasan_report.cold.8+0x242/0x309 mm/kasan/report.c:412
check_memory_region_inline mm/kasan/kasan.c:260 [inline]
check_memory_region+0x13e/0x1b0 mm/kasan/kasan.c:267
kasan_check_write+0x14/0x20 mm/kasan/kasan.c:278
atomic_dec include/asm-generic/atomic-instrumented.h:127 [inline]
hci_sock_release+0x14f/0x3b0 net/bluetooth/hci_sock.c:873
__sock_release+0xd7/0x250 net/socket.c:580
sock_close+0x19/0x20 net/socket.c:1142
__fput+0x3bc/0xa70 fs/file_table.c:279
____fput+0x15/0x20 fs/file_table.c:312
task_work_run+0x1e8/0x2a0 kernel/task_work.c:113
tracehook_notify_resume include/linux/tracehook.h:188 [inline]
exit_to_usermode_loop+0x318/0x380 arch/x86/entry/common.c:166
prepare_exit_to_usermode arch/x86/entry/common.c:197 [inline]
syscall_return_slowpath arch/x86/entry/common.c:268 [inline]
do_syscall_64+0x6be/0x820 arch/x86/entry/common.c:293
entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x457569
Code: fd b3 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7
48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff
ff 0f 83 cb b3 fb ff c3 66 2e 0f 1f 84 00 00 00 00
RSP: 002b:00007fb9b189cc78 EFLAGS: 00000246 ORIG_RAX: 0000000000000031
RAX: 0000000000000000 RBX: 0000000000000003 RCX: 0000000000457569
RDX: 000000000000000c RSI: 0000000020000240 RDI: 0000000000000006
RBP: 000000000072bfa0 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 00007fb9b189d6d4
R13: 00000000004bd6a4 R14: 00000000004cbf20 R15: 00000000ffffffff
Allocated by task 7468:
save_stack+0x43/0xd0 mm/kasan/kasan.c:448
set_track mm/kasan/kasan.c:460 [inline]
kasan_kmalloc+0xc7/0xe0 mm/kasan/kasan.c:553
kmem_cache_alloc_trace+0x152/0x750 mm/slab.c:3620
kmalloc include/linux/slab.h:546 [inline]
kzalloc include/linux/slab.h:741 [inline]
hci_alloc_dev+0x228/0x21a0 net/bluetooth/hci_core.c:3116
__vhci_create_device+0x102/0x580 drivers/bluetooth/hci_vhci.c:114
vhci_create_device drivers/bluetooth/hci_vhci.c:163 [inline]
vhci_get_user drivers/bluetooth/hci_vhci.c:219 [inline]
vhci_write+0x2de/0x470 drivers/bluetooth/hci_vhci.c:299
call_write_iter include/linux/fs.h:1844 [inline]
new_sync_write fs/read_write.c:474 [inline]
__vfs_write+0x6b8/0x9f0 fs/read_write.c:487
vfs_write+0x1fc/0x560 fs/read_write.c:549
ksys_write+0x101/0x260 fs/read_write.c:598
__do_sys_write fs/read_write.c:610 [inline]
__se_sys_write fs/read_write.c:607 [inline]
__x64_sys_write+0x73/0xb0 fs/read_write.c:607
do_syscall_64+0x1b9/0x820 arch/x86/entry/common.c:290
entry_SYSCALL_64_after_hwframe+0x49/0xbe
Freed by task 7467:
save_stack+0x43/0xd0 mm/kasan/kasan.c:448
set_track mm/kasan/kasan.c:460 [inline]
__kasan_slab_free+0x102/0x150 mm/kasan/kasan.c:521
kasan_slab_free+0xe/0x10 mm/kasan/kasan.c:528
__cache_free mm/slab.c:3498 [inline]
kfree+0xcf/0x230 mm/slab.c:3817
bt_host_release+0x19/0x30 net/bluetooth/hci_sysfs.c:86
device_release+0x7e/0x210 drivers/base/core.c:891
kobject_cleanup lib/kobject.c:662 [inline]
kobject_release lib/kobject.c:691 [inline]
kref_put include/linux/kref.h:70 [inline]
kobject_put.cold.9+0x287/0x2e4 lib/kobject.c:708
put_device+0x20/0x30 drivers/base/core.c:2024
hci_free_dev+0x19/0x20 net/bluetooth/hci_core.c:3208
vhci_release+0x7e/0xf0 drivers/bluetooth/hci_vhci.c:355
__fput+0x3bc/0xa70 fs/file_table.c:279
____fput+0x15/0x20 fs/file_table.c:312
task_work_run+0x1e8/0x2a0 kernel/task_work.c:113
tracehook_notify_resume include/linux/tracehook.h:188 [inline]
exit_to_usermode_loop+0x318/0x380 arch/x86/entry/common.c:166
prepare_exit_to_usermode arch/x86/entry/common.c:197 [inline]
syscall_return_slowpath arch/x86/entry/common.c:268 [inline]
do_syscall_64+0x6be/0x820 arch/x86/entry/common.c:293
entry_SYSCALL_64_after_hwframe+0x49/0xbe
The buggy address belongs to the object at ffff880182f48240
which belongs to the cache kmalloc-8k of size 8192
The buggy address is located 4192 bytes inside of
8192-byte region [ffff880182f48240, ffff880182f4a240)
The buggy address belongs to the page:
page:ffffea00060bd200 count:1 mapcount:0 mapping:ffff8801da802080 index:0x0
compound_mapcount: 0
flags: 0x2fffc0000010200(slab|head)
raw: 02fffc0000010200 ffffea000610f708 ffff8801da801b48 ffff8801da802080
raw: 0000000000000000 ffff880182f48240 0000000100000001 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff880182f49180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff880182f49200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> ffff880182f49280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff880182f49300: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff880182f49380: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================
audit: type=1800 audit(1540276897.489:32): pid=7430 uid=0 auid=4294967295
ses=4294967295 subj==unconfined op=collect_data cause=failed(directio)
comm="syz-executor5" name="file0" dev="sda1" ino=16559 res=0
syz-executor5 (7430) used greatest stack depth: 14640 bytes left
---
This bug is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.
syzbot will keep track of this bug report. See:
https://goo.gl/tpsmEJ#bug-status-tracking for how to communicate with
syzbot.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox