Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'net-Optimize-the-qed-allocations-inside-kdump-kernel'

Bhupesh Sharma says:

====================
net: Optimize the qed* allocations inside kdump kernel

Changes since v1:
----------------
- v1 can be seen here: http://lists.infradead.org/pipermail/kexec/2020-May/024935.html
- Addressed review comments received on v1:
* Removed unnecessary paranthesis.
* Used a different macro for minimum RX/TX ring count value in kdump
kernel.

Since kdump kernel(s) run under severe memory constraint with the
basic idea being to save the crashdump vmcore reliably when the primary
kernel panics/hangs, large memory allocations done by a network driver
can cause the crashkernel to panic with OOM.

The qed* drivers take up approximately 214MB memory when run in the
kdump kernel with the default configuration settings presently used in
the driver. With an usual crashkernel size of 512M, this allocation
is equal to almost half of the total crashkernel size allocated.

See some logs obtained via memstrack tool (see [1]) below:
dracut-pre-pivot[676]: ======== Report format module_summary: ========
dracut-pre-pivot[676]: Module qed using 149.6MB (2394 pages), peak allocation 149.6MB (2394 pages)
dracut-pre-pivot[676]: Module qede using 65.3MB (1045 pages), peak allocation 65.3MB (1045 pages)

This patchset tries to reduce the overall memory allocation profile of
the qed* driver when they run in the kdump kernel. With these
optimization we can see a saving of approx 85M in the kdump kernel:
dracut-pre-pivot[671]: ======== Report format module_summary: ========
dracut-pre-pivot[671]: Module qed using 124.6MB (1993 pages), peak allocation 124.7MB (1995 pages)
<..snip..>
dracut-pre-pivot[671]: Module qede using 4.6MB (73 pages), peak allocation 4.6MB (74 pages)

And the kdump kernel can save vmcore successfully via both ssh and nfs
interfaces.

This patchset contains two patches:
[PATCH 1/2] - Reduces the default TX and RX ring count in kdump kernel.
[PATCH 2/2] - Disables qed SRIOV feature in kdump kernel (as it is
normally not a supported kdump target for saving
vmcore).

[1]. Memstrack tool: https://github.com/ryncsn/memstrack
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+19 -6
+7 -3
drivers/net/ethernet/qlogic/qed/qed_sriov.h
··· 32 32 33 33 #ifndef _QED_SRIOV_H 34 34 #define _QED_SRIOV_H 35 + #include <linux/crash_dump.h> 35 36 #include <linux/types.h> 36 37 #include "qed_vf.h" 37 38 ··· 41 40 #define QED_VF_ARRAY_LENGTH (3) 42 41 43 42 #ifdef CONFIG_QED_SRIOV 44 - #define IS_VF(cdev) ((cdev)->b_is_vf) 45 - #define IS_PF(cdev) (!((cdev)->b_is_vf)) 46 - #define IS_PF_SRIOV(p_hwfn) (!!((p_hwfn)->cdev->p_iov_info)) 43 + #define IS_VF(cdev) (is_kdump_kernel() ? \ 44 + (0) : ((cdev)->b_is_vf)) 45 + #define IS_PF(cdev) (is_kdump_kernel() ? \ 46 + (1) : !((cdev)->b_is_vf)) 47 + #define IS_PF_SRIOV(p_hwfn) (is_kdump_kernel() ? \ 48 + (0) : !!((p_hwfn)->cdev->p_iov_info)) 47 49 #else 48 50 #define IS_VF(cdev) (0) 49 51 #define IS_PF(cdev) (1)
+2
drivers/net/ethernet/qlogic/qede/qede.h
··· 575 575 #define RX_RING_SIZE ((u16)BIT(RX_RING_SIZE_POW)) 576 576 #define NUM_RX_BDS_MAX (RX_RING_SIZE - 1) 577 577 #define NUM_RX_BDS_MIN 128 578 + #define NUM_RX_BDS_KDUMP_MIN 63 578 579 #define NUM_RX_BDS_DEF ((u16)BIT(10) - 1) 579 580 580 581 #define TX_RING_SIZE_POW 13 581 582 #define TX_RING_SIZE ((u16)BIT(TX_RING_SIZE_POW)) 582 583 #define NUM_TX_BDS_MAX (TX_RING_SIZE - 1) 583 584 #define NUM_TX_BDS_MIN 128 585 + #define NUM_TX_BDS_KDUMP_MIN 63 584 586 #define NUM_TX_BDS_DEF NUM_TX_BDS_MAX 585 587 586 588 #define QEDE_MIN_PKT_LEN 64
+10 -3
drivers/net/ethernet/qlogic/qede/qede_main.c
··· 29 29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 30 * SOFTWARE. 31 31 */ 32 + #include <linux/crash_dump.h> 32 33 #include <linux/module.h> 33 34 #include <linux/pci.h> 34 35 #include <linux/version.h> ··· 716 715 edev->dp_module = dp_module; 717 716 edev->dp_level = dp_level; 718 717 edev->ops = qed_ops; 719 - edev->q_num_rx_buffers = NUM_RX_BDS_DEF; 720 - edev->q_num_tx_buffers = NUM_TX_BDS_DEF; 718 + 719 + if (is_kdump_kernel()) { 720 + edev->q_num_rx_buffers = NUM_RX_BDS_KDUMP_MIN; 721 + edev->q_num_tx_buffers = NUM_TX_BDS_KDUMP_MIN; 722 + } else { 723 + edev->q_num_rx_buffers = NUM_RX_BDS_DEF; 724 + edev->q_num_tx_buffers = NUM_TX_BDS_DEF; 725 + } 721 726 722 727 DP_INFO(edev, "Allocated netdev with %d tx queues and %d rx queues\n", 723 728 info->num_queues, info->num_queues); ··· 1214 1207 case QEDE_PRIVATE_VF: 1215 1208 if (debug & QED_LOG_VERBOSE_MASK) 1216 1209 dev_err(&pdev->dev, "Probing a VF\n"); 1217 - is_vf = true; 1210 + is_vf = is_kdump_kernel() ? false : true; 1218 1211 break; 1219 1212 default: 1220 1213 if (debug & QED_LOG_VERBOSE_MASK)