@@ -78,6 +78,77 @@ void efx_update_debugfs_netdev(struct efx_nic *efx)
mutex_unlock(&efx->debugfs_symlink_mutex);
}
+#define EFX_DEBUGFS_TXQ(_type, _name) \
+ debugfs_create_##_type(#_name, 0444, tx_queue->debug_dir, &tx_queue->_name)
+
+/* Create basic debugfs parameter files for an Efx TXQ */
+static void efx_init_debugfs_tx_queue_files(struct efx_tx_queue *tx_queue)
+{
+ EFX_DEBUGFS_TXQ(u32, label);
+ EFX_DEBUGFS_TXQ(bool, xdp_tx);
+ /* offload features */
+ EFX_DEBUGFS_TXQ(u32, type);
+ EFX_DEBUGFS_TXQ(u32, tso_version);
+ EFX_DEBUGFS_TXQ(bool, tso_encap);
+ EFX_DEBUGFS_TXQ(bool, timestamping);
+ /* descriptor ring indices */
+ EFX_DEBUGFS_TXQ(u32, read_count);
+ EFX_DEBUGFS_TXQ(u32, insert_count);
+ EFX_DEBUGFS_TXQ(u32, write_count);
+ EFX_DEBUGFS_TXQ(u32, notify_count);
+}
+
+/**
+ * efx_init_debugfs_tx_queue - create debugfs directory for TX queue
+ * @tx_queue: Efx TX queue
+ *
+ * Create a debugfs directory containing parameter-files for @tx_queue.
+ * The directory must be cleaned up using efx_fini_debugfs_tx_queue(),
+ * even if this function returns an error.
+ *
+ * Return: a negative error code or 0 on success.
+ */
+int efx_init_debugfs_tx_queue(struct efx_tx_queue *tx_queue)
+{
+ char target[EFX_DEBUGFS_NAME_LEN];
+ char name[EFX_DEBUGFS_NAME_LEN];
+
+ if (!tx_queue->efx->debug_queues_dir)
+ return -ENODEV;
+ /* Create directory */
+ if (snprintf(name, sizeof(name), "tx-%d", tx_queue->queue)
+ >= sizeof(name))
+ return -ENAMETOOLONG;
+ tx_queue->debug_dir = debugfs_create_dir(name,
+ tx_queue->efx->debug_queues_dir);
+ if (!tx_queue->debug_dir)
+ return -ENOMEM;
+
+ /* Create files */
+ efx_init_debugfs_tx_queue_files(tx_queue);
+
+ /* Create symlink to channel */
+ if (snprintf(target, sizeof(target), "../../channels/%d",
+ tx_queue->channel->channel) >= sizeof(target))
+ return -ENAMETOOLONG;
+ if (!debugfs_create_symlink("channel", tx_queue->debug_dir, target))
+ return -ENOMEM;
+
+ return 0;
+}
+
+/**
+ * efx_fini_debugfs_tx_queue - remove debugfs directory for TX queue
+ * @tx_queue: Efx TX queue
+ *
+ * Remove directory created for @tx_queue by efx_init_debugfs_tx_queue().
+ */
+void efx_fini_debugfs_tx_queue(struct efx_tx_queue *tx_queue)
+{
+ debugfs_remove_recursive(tx_queue->debug_dir);
+ tx_queue->debug_dir = NULL;
+}
+
#define EFX_DEBUGFS_RXQ(_type, _name) \
debugfs_create_##_type(#_name, 0444, rx_queue->debug_dir, &rx_queue->_name)
@@ -34,11 +34,19 @@
* (&efx_rx_queue.debug_dir), whose name is "rx-N" where N is the RX queue
* index. (This may not be the same as the kernel core RX queue index.)
* The directory will contain a symlink to the owning channel.
+ * * For each NIC TX queue, this will contain a directory
+ * (&efx_tx_queue.debug_dir), whose name is "tx-N" where N is the TX queue
+ * index. (This may differ from both the kernel core TX queue index and
+ * the hardware queue label of the TXQ.)
+ * The directory will contain a symlink to the owning channel.
*/
void efx_fini_debugfs_netdev(struct net_device *net_dev);
void efx_update_debugfs_netdev(struct efx_nic *efx);
+int efx_init_debugfs_tx_queue(struct efx_tx_queue *tx_queue);
+void efx_fini_debugfs_tx_queue(struct efx_tx_queue *tx_queue);
+
int efx_init_debugfs_rx_queue(struct efx_rx_queue *rx_queue);
void efx_fini_debugfs_rx_queue(struct efx_rx_queue *rx_queue);
@@ -57,6 +65,12 @@ static inline void efx_fini_debugfs_netdev(struct net_device *net_dev) {}
static inline void efx_update_debugfs_netdev(struct efx_nic *efx) {}
+int efx_init_debugfs_tx_queue(struct efx_tx_queue *tx_queue)
+{
+ return 0;
+}
+void efx_fini_debugfs_tx_queue(struct efx_tx_queue *tx_queue) {}
+
int efx_init_debugfs_rx_queue(struct efx_rx_queue *rx_queue)
{
return 0;
@@ -273,6 +273,10 @@ struct efx_tx_queue {
bool initialised;
bool timestamping;
bool xdp_tx;
+#ifdef CONFIG_DEBUG_FS
+ /** @debug_dir: Queue debugfs directory (under @efx->debug_queues_dir) */
+ struct dentry *debug_dir;
+#endif
/* Members used mainly on the completion path */
unsigned int read_count ____cacheline_aligned_in_smp;
@@ -12,6 +12,7 @@
#include "efx.h"
#include "nic_common.h"
#include "tx_common.h"
+#include "debugfs.h"
#include <net/gso.h>
static unsigned int efx_tx_cb_page_count(struct efx_tx_queue *tx_queue)
@@ -47,6 +48,11 @@ int efx_probe_tx_queue(struct efx_tx_queue *tx_queue)
rc = -ENOMEM;
goto fail1;
}
+ rc = efx_init_debugfs_tx_queue(tx_queue);
+ if (rc) /* not fatal */
+ netif_err(efx, drv, efx->net_dev,
+ "Failed to create debugfs for TXQ %d, rc=%d\n",
+ tx_queue->queue, rc);
/* Allocate hardware ring, determine TXQ type */
rc = efx_nic_probe_tx(tx_queue);
@@ -133,6 +139,8 @@ void efx_remove_tx_queue(struct efx_tx_queue *tx_queue)
"destroying TX queue %d\n", tx_queue->queue);
efx_nic_remove_tx(tx_queue);
+ efx_fini_debugfs_tx_queue(tx_queue);
+
if (tx_queue->cb_page) {
for (i = 0; i < efx_tx_cb_page_count(tx_queue); i++)
efx_nic_free_buffer(tx_queue->efx,