[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <182a168b-2898-4517-b2b9-8ef93ef72292@amd.com>
Date: Thu, 14 Dec 2023 16:05:27 -0800
From: "Nelson, Shannon" <shannon.nelson@....com>
To: edward.cree@....com, linux-net-drivers@....com, davem@...emloft.net,
kuba@...nel.org, pabeni@...hat.com, edumazet@...gle.com
Cc: Edward Cree <ecree.xilinx@...il.com>, netdev@...r.kernel.org,
habetsm.xilinx@...il.com, Jonathan Cooper <jonathan.s.cooper@....com>
Subject: Re: [PATCH net-next 1/7] sfc: initial debugfs implementation
On 12/11/2023 9:18 AM, edward.cree@....com wrote:
>
> From: Edward Cree <ecree.xilinx@...il.com>
>
Hi Ed, a few minor nits I thought I'd call out.
Cheers,
sln
> Just a handful of nodes, including one enum with a string table for
> pretty printing the values.
It would be nice to have a couple of example paths listed here
>
> Reviewed-by: Jonathan Cooper <jonathan.s.cooper@....com>
> Signed-off-by: Edward Cree <ecree.xilinx@...il.com>
> ---
> drivers/net/ethernet/sfc/Makefile | 1 +
> drivers/net/ethernet/sfc/debugfs.c | 234 ++++++++++++++++++++++++
> drivers/net/ethernet/sfc/debugfs.h | 56 ++++++
> drivers/net/ethernet/sfc/ef10.c | 10 +
> drivers/net/ethernet/sfc/ef100_netdev.c | 7 +
> drivers/net/ethernet/sfc/ef100_nic.c | 8 +
> drivers/net/ethernet/sfc/efx.c | 15 +-
> drivers/net/ethernet/sfc/efx_common.c | 7 +
> drivers/net/ethernet/sfc/net_driver.h | 29 +++
> 9 files changed, 366 insertions(+), 1 deletion(-)
> create mode 100644 drivers/net/ethernet/sfc/debugfs.c
> create mode 100644 drivers/net/ethernet/sfc/debugfs.h
>
> diff --git a/drivers/net/ethernet/sfc/Makefile b/drivers/net/ethernet/sfc/Makefile
> index 8f446b9bd5ee..1fbdd04dc2c5 100644
> --- a/drivers/net/ethernet/sfc/Makefile
> +++ b/drivers/net/ethernet/sfc/Makefile
> @@ -12,6 +12,7 @@ sfc-$(CONFIG_SFC_MTD) += mtd.o
> sfc-$(CONFIG_SFC_SRIOV) += sriov.o ef10_sriov.o ef100_sriov.o ef100_rep.o \
> mae.o tc.o tc_bindings.o tc_counters.o \
> tc_encap_actions.o tc_conntrack.o
> +sfc-$(CONFIG_DEBUG_FS) += debugfs.o
Just as you are using #ifdef CONFIG_DEBUG_FS in your debugfs.h, you
could use it in your debugfs.c and simply add the .o file to your sfc-y
list here.
>
> obj-$(CONFIG_SFC) += sfc.o
>
> diff --git a/drivers/net/ethernet/sfc/debugfs.c b/drivers/net/ethernet/sfc/debugfs.c
> new file mode 100644
> index 000000000000..cf800addb4ff
> --- /dev/null
> +++ b/drivers/net/ethernet/sfc/debugfs.c
> @@ -0,0 +1,234 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/****************************************************************************
> + * Driver for Solarflare network controllers and boards
> + * Copyright 2023, Advanced Micro Devices, Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 as published
> + * by the Free Software Foundation, incorporated herein by reference.
> + */
> +
> +#include "debugfs.h"
> +#include <linux/module.h>
> +#include <linux/debugfs.h>
> +#include <linux/dcache.h>
> +#include <linux/seq_file.h>
> +
> +/* Maximum length for a name component or symlink target */
> +#define EFX_DEBUGFS_NAME_LEN 32
> +
> +/* Top-level debug directory ([/sys/kernel]/debug/sfc) */
> +static struct dentry *efx_debug_root;
> +
> +/* "cards" directory ([/sys/kernel]/debug/sfc/cards) */
> +static struct dentry *efx_debug_cards;
> +
> +/**
> + * efx_init_debugfs_netdev - create debugfs sym-link for net device
> + * @net_dev: Net device
> + *
> + * Create sym-link named after @net_dev to the debugfs directories for the
> + * corresponding NIC. The sym-link must be cleaned up using
> + * efx_fini_debugfs_netdev().
> + *
> + * Return: a negative error code or 0 on success.
> + */
> +static int efx_init_debugfs_netdev(struct net_device *net_dev)
> +{
> + struct efx_nic *efx = efx_netdev_priv(net_dev);
> + char target[EFX_DEBUGFS_NAME_LEN];
> + char name[EFX_DEBUGFS_NAME_LEN];
> +
> + if (snprintf(name, sizeof(name), "nic_%s", net_dev->name) >=
> + sizeof(name))
> + return -ENAMETOOLONG;
> + if (snprintf(target, sizeof(target), "cards/%s", pci_name(efx->pci_dev))
> + >= sizeof(target))
> + return -ENAMETOOLONG;
> + efx->debug_symlink = debugfs_create_symlink(name,
> + efx_debug_root, target);
> + if (IS_ERR_OR_NULL(efx->debug_symlink))
> + return efx->debug_symlink ? PTR_ERR(efx->debug_symlink) :
> + -ENOMEM;
> +
> + return 0;
> +}
> +
> +/**
> + * efx_fini_debugfs_netdev - remove debugfs sym-link for net device
> + * @net_dev: Net device
> + *
> + * Remove sym-link created for @net_dev by efx_init_debugfs_netdev().
> + */
> +void efx_fini_debugfs_netdev(struct net_device *net_dev)
> +{
> + struct efx_nic *efx = efx_netdev_priv(net_dev);
> +
> + debugfs_remove(efx->debug_symlink);
> + efx->debug_symlink = NULL;
> +}
> +
> +/* replace debugfs sym-links on net device rename */
> +void efx_update_debugfs_netdev(struct efx_nic *efx)
> +{
> + mutex_lock(&efx->debugfs_symlink_mutex);
> + if (efx->debug_symlink)
> + efx_fini_debugfs_netdev(efx->net_dev);
> + efx_init_debugfs_netdev(efx->net_dev);
> + mutex_unlock(&efx->debugfs_symlink_mutex);
> +}
How necessary is this netdev symlink? This seems like a bunch of extra
maintenance.
> +
> +static int efx_debugfs_enum_read(struct seq_file *s, void *d)
> +{
> + struct efx_debugfs_enum_data *data = s->private;
> + u64 value = 0;
> + size_t len;
> +
> + len = min(data->vlen, sizeof(value));
> +#ifdef BIG_ENDIAN
> + /* If data->value is narrower than u64, we need to copy into the
> + * far end of value, as that's where the low bits live.
> + */
> + memcpy(((void *)&value) + sizeof(value) - len, data->value, len);
> +#else
> + memcpy(&value, data->value, len);
> +#endif
> + seq_printf(s, "%#llx => %s\n", value,
> + value < data->max ? data->names[value] : "(invalid)");
> + return 0;
> +}
> +
> +static int efx_debugfs_enum_open(struct inode *inode, struct file *f)
> +{
> + struct efx_debugfs_enum_data *data = inode->i_private;
> +
> + return single_open(f, efx_debugfs_enum_read, data);
> +}
> +
> +static const struct file_operations efx_debugfs_enum_ops = {
> + .owner = THIS_MODULE,
> + .open = efx_debugfs_enum_open,
> + .release = single_release,
> + .read = seq_read,
> + .llseek = seq_lseek,
> +};
> +
> +static void efx_debugfs_create_enum(const char *name, umode_t mode,
> + struct dentry *parent,
> + struct efx_debugfs_enum_data *data)
> +{
> + debugfs_create_file(name, mode, parent, data, &efx_debugfs_enum_ops);
> +}
> +
> +static const char *const efx_interrupt_mode_names[] = {
> + [EFX_INT_MODE_MSIX] = "MSI-X",
> + [EFX_INT_MODE_MSI] = "MSI",
> + [EFX_INT_MODE_LEGACY] = "legacy",
> +};
> +
> +#define EFX_DEBUGFS_EFX(_type, _name) \
> + debugfs_create_##_type(#_name, 0444, efx->debug_dir, &efx->_name)
> +
> +/* Create basic debugfs parameter files for an Efx NIC */
> +static void efx_init_debugfs_nic_files(struct efx_nic *efx)
> +{
> + EFX_DEBUGFS_EFX(x32, rx_dma_len);
> + EFX_DEBUGFS_EFX(x32, rx_buffer_order);
> + EFX_DEBUGFS_EFX(x32, rx_buffer_truesize);
> + efx->debug_interrupt_mode.max = ARRAY_SIZE(efx_interrupt_mode_names);
> + efx->debug_interrupt_mode.names = efx_interrupt_mode_names;
> + efx->debug_interrupt_mode.vlen = sizeof(efx->interrupt_mode);
> + efx->debug_interrupt_mode.value = &efx->interrupt_mode;
> + efx_debugfs_create_enum("interrupt_mode", 0444, efx->debug_dir,
> + &efx->debug_interrupt_mode);
> +}
> +
> +/**
> + * efx_init_debugfs_nic - create debugfs directory for NIC
> + * @efx: Efx NIC
> + *
> + * Create debugfs directory containing parameter-files for @efx.
> + * The directory must be cleaned up using efx_fini_debugfs_nic().
> + *
> + * Return: a negative error code or 0 on success.
> + */
> +int efx_init_debugfs_nic(struct efx_nic *efx)
> +{
> + /* Create directory */
> + efx->debug_dir = debugfs_create_dir(pci_name(efx->pci_dev),
> + efx_debug_cards);
> + if (!efx->debug_dir)
> + return -ENOMEM;
> + efx_init_debugfs_nic_files(efx);
> + return 0;
> +}
> +
> +/**
> + * efx_fini_debugfs_nic - remove debugfs directory for NIC
> + * @efx: Efx NIC
> + *
> + * Remove debugfs directory created for @efx by efx_init_debugfs_nic().
> + */
> +void efx_fini_debugfs_nic(struct efx_nic *efx)
> +{
> + debugfs_remove_recursive(efx->debug_dir);
> + efx->debug_dir = NULL;
> +}
> +
> +/**
> + * efx_init_debugfs - create debugfs directories for sfc driver
> + *
> + * Create debugfs directories "sfc" and "sfc/cards". This must be
> + * called before any of the other functions that create debugfs
> + * directories. The directories must be cleaned up using
> + * efx_fini_debugfs().
> + *
> + * Return: a negative error code or 0 on success.
> + */
> +int efx_init_debugfs(void)
> +{
> + int rc;
> +
> + /* Create top-level directory */
> + efx_debug_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
> + if (!efx_debug_root) {
> + pr_err("debugfs_create_dir %s failed.\n", KBUILD_MODNAME);
> + rc = -ENOMEM;
> + goto err;
> + } else if (IS_ERR(efx_debug_root)) {
> + rc = PTR_ERR(efx_debug_root);
> + pr_err("debugfs_create_dir %s failed, rc=%d.\n",
> + KBUILD_MODNAME, rc);
> + goto err;
> + }
> +
> + /* Create "cards" directory */
> + efx_debug_cards = debugfs_create_dir("cards", efx_debug_root);
> + if (!efx_debug_cards) {
> + pr_err("debugfs_create_dir cards failed.\n");
> + rc = -ENOMEM;
> + goto err;
> + } else if (IS_ERR(efx_debug_cards)) {
> + rc = PTR_ERR(efx_debug_cards);
> + pr_err("debugfs_create_dir cards failed, rc=%d.\n", rc);
> + goto err;
> + }
> +
> + return 0;
> +
> +err:
> + efx_fini_debugfs();
> + return rc;
> +}
> +
> +/**
> + * efx_fini_debugfs - remove debugfs directories for sfc driver
> + *
> + * Remove directories created by efx_init_debugfs().
> + */
> +void efx_fini_debugfs(void)
> +{
> + debugfs_remove_recursive(efx_debug_root);
> + efx_debug_cards = NULL;
> + efx_debug_root = NULL;
> +}
> diff --git a/drivers/net/ethernet/sfc/debugfs.h b/drivers/net/ethernet/sfc/debugfs.h
> new file mode 100644
> index 000000000000..1fe40fbffa5e
> --- /dev/null
> +++ b/drivers/net/ethernet/sfc/debugfs.h
> @@ -0,0 +1,56 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/****************************************************************************
> + * Driver for Solarflare network controllers and boards
> + * Copyright 2023, Advanced Micro Devices, Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 as published
> + * by the Free Software Foundation, incorporated herein by reference.
> + */
> +
> +#ifndef EFX_DEBUGFS_H
> +#define EFX_DEBUGFS_H
> +#include "net_driver.h"
> +
> +#ifdef CONFIG_DEBUG_FS
> +
> +/**
> + * DOC: Directory layout for sfc debugfs
> + *
> + * At top level ([/sys/kernel]/debug/sfc) are per-netdev symlinks "nic_$name"
> + * and the "cards" directory. For each PCI device to which the driver has
> + * bound and created a &struct efx_nic, there is a directory &efx_nic.debug_dir
> + * in "cards" whose name is the PCI address of the device; it is to this
> + * directory that the netdev symlink points.
> + */
> +
> +void efx_fini_debugfs_netdev(struct net_device *net_dev);
> +void efx_update_debugfs_netdev(struct efx_nic *efx);
> +
> +int efx_init_debugfs_nic(struct efx_nic *efx);
> +void efx_fini_debugfs_nic(struct efx_nic *efx);
> +
> +int efx_init_debugfs(void);
> +void efx_fini_debugfs(void);
> +
> +#else /* CONFIG_DEBUG_FS */
> +
> +static inline void efx_fini_debugfs_netdev(struct net_device *net_dev) {}
> +
> +static inline void efx_update_debugfs_netdev(struct efx_nic *efx) {}
> +
> +static inline int efx_init_debugfs_nic(struct efx_nic *efx)
> +{
> + return 0;
> +}
> +static inline void efx_fini_debugfs_nic(struct efx_nic *efx) {}
> +
> +static inline int efx_init_debugfs(void)
> +{
> + return 0;
> +}
> +static inline void efx_fini_debugfs(void) {}
> +
> +#endif /* CONFIG_DEBUG_FS */
> +
> +#endif /* EFX_DEBUGFS_H */
> diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
> index 6dfa062feebc..58e18fc92093 100644
> --- a/drivers/net/ethernet/sfc/ef10.c
> +++ b/drivers/net/ethernet/sfc/ef10.c
> @@ -19,6 +19,7 @@
> #include "workarounds.h"
> #include "selftest.h"
> #include "ef10_sriov.h"
> +#include "debugfs.h"
> #include <linux/in.h>
> #include <linux/jhash.h>
> #include <linux/wait.h>
> @@ -580,6 +581,13 @@ static int efx_ef10_probe(struct efx_nic *efx)
> if (rc)
> goto fail3;
>
> + /* Populate debugfs */
> +#ifdef CONFIG_DEBUG_FS
> + rc = efx_init_debugfs_nic(efx);
> + if (rc)
> + pci_err(efx->pci_dev, "failed to init device debugfs\n");
> +#endif
I don't think you need the ifdef here because you have the static
version defined in debugfs.h
> +
> rc = device_create_file(&efx->pci_dev->dev,
> &dev_attr_link_control_flag);
> if (rc)
> @@ -693,6 +701,7 @@ static int efx_ef10_probe(struct efx_nic *efx)
> fail4:
> device_remove_file(&efx->pci_dev->dev, &dev_attr_link_control_flag);
> fail3:
> + efx_fini_debugfs_nic(efx);
> efx_mcdi_detach(efx);
>
> mutex_lock(&nic_data->udp_tunnels_lock);
> @@ -962,6 +971,7 @@ static void efx_ef10_remove(struct efx_nic *efx)
> device_remove_file(&efx->pci_dev->dev, &dev_attr_link_control_flag);
>
> efx_mcdi_detach(efx);
> + efx_fini_debugfs_nic(efx);
>
> memset(nic_data->udp_tunnels, 0, sizeof(nic_data->udp_tunnels));
> mutex_lock(&nic_data->udp_tunnels_lock);
> diff --git a/drivers/net/ethernet/sfc/ef100_netdev.c b/drivers/net/ethernet/sfc/ef100_netdev.c
> index 7f7d560cb2b4..e844d57754b7 100644
> --- a/drivers/net/ethernet/sfc/ef100_netdev.c
> +++ b/drivers/net/ethernet/sfc/ef100_netdev.c
> @@ -26,10 +26,12 @@
> #include "tc_bindings.h"
> #include "tc_encap_actions.h"
> #include "efx_devlink.h"
> +#include "debugfs.h"
>
> static void ef100_update_name(struct efx_nic *efx)
> {
> strcpy(efx->name, efx->net_dev->name);
> + efx_update_debugfs_netdev(efx);
> }
>
> static int ef100_alloc_vis(struct efx_nic *efx, unsigned int *allocated_vis)
> @@ -405,6 +407,11 @@ void ef100_remove_netdev(struct efx_probe_data *probe_data)
> ef100_pf_unset_devlink_port(efx);
> efx_fini_tc(efx);
> #endif
> +#ifdef CONFIG_DEBUG_FS
> + mutex_lock(&efx->debugfs_symlink_mutex);
> + efx_fini_debugfs_netdev(efx->net_dev);
> + mutex_unlock(&efx->debugfs_symlink_mutex);
> +#endif
Can you do the mutex dance inside of efx_fini_debugfs_netdev() and then
not need the ifdef here?
>
> down_write(&efx->filter_sem);
> efx_mcdi_filter_table_remove(efx);
> diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c
> index 6da06931187d..ad378aa05dc3 100644
> --- a/drivers/net/ethernet/sfc/ef100_nic.c
> +++ b/drivers/net/ethernet/sfc/ef100_nic.c
> @@ -27,6 +27,7 @@
> #include "tc.h"
> #include "mae.h"
> #include "rx_common.h"
> +#include "debugfs.h"
>
> #define EF100_MAX_VIS 4096
> #define EF100_NUM_MCDI_BUFFERS 1
> @@ -1077,6 +1078,12 @@ static int ef100_probe_main(struct efx_nic *efx)
>
> /* Post-IO section. */
>
> + /* Populate debugfs */
> +#ifdef CONFIG_DEBUG_FS
> + rc = efx_init_debugfs_nic(efx);
> + if (rc)
> + pci_err(efx->pci_dev, "failed to init device debugfs\n");
> +#endif
Shouldn't need the ifdef
> rc = efx_mcdi_init(efx);
> if (rc)
> goto fail;
> @@ -1213,6 +1220,7 @@ void ef100_remove(struct efx_nic *efx)
>
> efx_mcdi_detach(efx);
> efx_mcdi_fini(efx);
> + efx_fini_debugfs_nic(efx);
> if (nic_data)
> efx_nic_free_buffer(efx, &nic_data->mcdi_buf);
> kfree(nic_data);
> diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
> index 19f4b4d0b851..9266c7b5b4fd 100644
> --- a/drivers/net/ethernet/sfc/efx.c
> +++ b/drivers/net/ethernet/sfc/efx.c
> @@ -33,6 +33,7 @@
> #include "selftest.h"
> #include "sriov.h"
> #include "efx_devlink.h"
> +#include "debugfs.h"
>
> #include "mcdi_port_common.h"
> #include "mcdi_pcol.h"
> @@ -401,6 +402,11 @@ static void efx_remove_all(struct efx_nic *efx)
> #endif
> efx_remove_port(efx);
> efx_remove_nic(efx);
> +#ifdef CONFIG_DEBUG_FS
> + mutex_lock(&efx->debugfs_symlink_mutex);
> + efx_fini_debugfs_netdev(efx->net_dev);
> + mutex_unlock(&efx->debugfs_symlink_mutex);
> +#endif
Same mutex comment
> }
>
> /**************************************************************************
> @@ -667,6 +673,7 @@ static void efx_update_name(struct efx_nic *efx)
> strcpy(efx->name, efx->net_dev->name);
> efx_mtd_rename(efx);
> efx_set_channel_names(efx);
> + efx_update_debugfs_netdev(efx);
> }
>
> static int efx_netdev_event(struct notifier_block *this,
> @@ -1319,6 +1326,10 @@ static int __init efx_init_module(void)
>
> printk(KERN_INFO "Solarflare NET driver\n");
>
> + rc = efx_init_debugfs();
> + if (rc)
> + goto err_debugfs;
> +
> rc = register_netdevice_notifier(&efx_netdev_notifier);
> if (rc)
> goto err_notifier;
> @@ -1344,6 +1355,8 @@ static int __init efx_init_module(void)
> err_reset:
> unregister_netdevice_notifier(&efx_netdev_notifier);
> err_notifier:
> + efx_fini_debugfs();
> + err_debugfs:
> return rc;
> }
>
> @@ -1355,7 +1368,7 @@ static void __exit efx_exit_module(void)
> pci_unregister_driver(&efx_pci_driver);
> efx_destroy_reset_workqueue();
> unregister_netdevice_notifier(&efx_netdev_notifier);
> -
> + efx_fini_debugfs();
> }
>
> module_init(efx_init_module);
> diff --git a/drivers/net/ethernet/sfc/efx_common.c b/drivers/net/ethernet/sfc/efx_common.c
> index 175bd9cdfdac..7a9d6b6b66e5 100644
> --- a/drivers/net/ethernet/sfc/efx_common.c
> +++ b/drivers/net/ethernet/sfc/efx_common.c
> @@ -1022,6 +1022,9 @@ int efx_init_struct(struct efx_nic *efx, struct pci_dev *pci_dev)
> INIT_WORK(&efx->mac_work, efx_mac_work);
> init_waitqueue_head(&efx->flush_wq);
>
> +#ifdef CONFIG_DEBUG_FS
> + mutex_init(&efx->debugfs_symlink_mutex);
> +#endif
Can we do this without the ifdefs in the mainline code?
(okay, I'll stop grinding on that one for now)
> efx->tx_queues_per_channel = 1;
> efx->rxq_entries = EFX_DEFAULT_DMAQ_SIZE;
> efx->txq_entries = EFX_DEFAULT_DMAQ_SIZE;
> @@ -1056,6 +1059,10 @@ void efx_fini_struct(struct efx_nic *efx)
>
> efx_fini_channels(efx);
>
> +#ifdef CONFIG_DEBUG_FS
> + mutex_destroy(&efx->debugfs_symlink_mutex);
> +#endif
> +
> kfree(efx->vpd_sn);
>
> if (efx->workqueue) {
> diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
> index 27d86e90a3bb..961e2db31c6e 100644
> --- a/drivers/net/ethernet/sfc/net_driver.h
> +++ b/drivers/net/ethernet/sfc/net_driver.h
> @@ -107,6 +107,24 @@ struct hwtstamp_config;
>
> struct efx_self_tests;
>
> +/**
> + * struct efx_debugfs_enum_data - information for pretty-printing enums
> + * @value: pointer to the actual enum
> + * @vlen: sizeof the enum
> + * @names: array of names of enumerated values. May contain some %NULL entries.
> + * @max: number of entries in @names, typically from ARRAY_SIZE()
> + *
> + * Where a driver struct contains an enum member which we wish to expose in
> + * debugfs, we also embed an instance of this struct, which
> + * efx_debugfs_enum_read() uses to pretty-print the value.
> + */
> +struct efx_debugfs_enum_data {
> + void *value;
> + size_t vlen;
> + const char *const *names;
> + unsigned int max;
> +};
> +
> /**
> * struct efx_buffer - A general-purpose DMA buffer
> * @addr: host base address of the buffer
> @@ -1123,6 +1141,17 @@ struct efx_nic {
> u32 rps_next_id;
> #endif
>
> +#ifdef CONFIG_DEBUG_FS
> + /** @debug_dir: NIC debugfs directory */
> + struct dentry *debug_dir;
> + /** @debug_symlink: NIC debugfs symlink (``nic_eth%d``) */
> + struct dentry *debug_symlink;
> + /** @debug_interrupt_mode: debugfs details for printing @interrupt_mode */
> + struct efx_debugfs_enum_data debug_interrupt_mode;
> + /** @debugfs_symlink_mutex: protects debugfs @debug_symlink */
> + struct mutex debugfs_symlink_mutex;
> +#endif
> +
> atomic_t active_queues;
> atomic_t rxq_flush_pending;
> atomic_t rxq_flush_outstanding;
>
Powered by blists - more mailing lists