* [PATCH net-next v2 0/4] sfc: add MCDI tracing
@ 2015-05-20 15:49 Edward Cree
2015-05-20 15:49 ` [PATCH net-next 1/4] sfc: add tracing of MCDI commands Edward Cree
` (4 more replies)
0 siblings, 5 replies; 8+ messages in thread
From: Edward Cree @ 2015-05-20 15:49 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
This patchset adds support for logging MCDI (Management-Controller-to-
Driver Interface) interactions between the sfc driver and a bound device,
to aid in debugging.
Solarflare has a tool to decode the resulting traces and will look to
open-source this if there is any external interest, but the protocol is
already detailed in drivers/net/ethernet/sfc/mcdi_pcol.h.
--
v2: avoid long lines in cover letter; fix multiline comment style
Edward Cree (3):
sfc: add tracing of MCDI commands
sfc: add sysfs entry to control MCDI tracing
sfc: add module parameter to enable MCDI logging on new functions
Jon Cooper (1):
sfc: Initialise MCDI buffers to 0 on declaration.
drivers/net/ethernet/sfc/Kconfig | 9 ++++
drivers/net/ethernet/sfc/ef10.c | 27 ++++++----
drivers/net/ethernet/sfc/efx.c | 49 +++++++++++++++---
drivers/net/ethernet/sfc/mcdi.c | 108 ++++++++++++++++++++++++++++++++++++---
drivers/net/ethernet/sfc/mcdi.h | 14 +++--
drivers/net/ethernet/sfc/ptp.c | 6 +--
6 files changed, 181 insertions(+), 32 deletions(-)
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH net-next 1/4] sfc: add tracing of MCDI commands
2015-05-20 15:49 [PATCH net-next v2 0/4] sfc: add MCDI tracing Edward Cree
@ 2015-05-20 15:49 ` Edward Cree
2015-05-20 15:50 ` [PATCH net-next 2/4] sfc: add sysfs entry to control MCDI tracing Edward Cree
` (3 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Edward Cree @ 2015-05-20 15:49 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
MCDI tracing is conditional on CONFIG_SFC_MCDI_LOGGING, which is enabled
by default.
Each MCDI command will produce a console line like
sfc dom:bus:dev:fn ifname: MCDI RPC REQ: xxxxxxxx [yyyyyyyy...]
where xxxxxxxx etc. are the raw MCDI payload in 32-bit hex chunks.
The response will then produce a similar line with "RESP" instead of "REQ",
and containing the MCDI response payload (if any).
Signed-off-by: Edward Cree <ecree@solarflare.com>
---
drivers/net/ethernet/sfc/Kconfig | 8 ++++
drivers/net/ethernet/sfc/ef10.c | 3 ++
drivers/net/ethernet/sfc/mcdi.c | 91 ++++++++++++++++++++++++++++++++++++++--
drivers/net/ethernet/sfc/mcdi.h | 4 ++
4 files changed, 102 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/sfc/Kconfig b/drivers/net/ethernet/sfc/Kconfig
index 0889212..c4ba42b 100644
--- a/drivers/net/ethernet/sfc/Kconfig
+++ b/drivers/net/ethernet/sfc/Kconfig
@@ -36,3 +36,11 @@ config SFC_SRIOV
This enables support for the SFC9000 I/O Virtualization
features, allowing accelerated network performance in
virtualized environments.
+config SFC_MCDI_LOGGING
+ bool "Solarflare SFC9000/SFC9100-family MCDI logging support"
+ depends on SFC
+ default y
+ ---help---
+ This enables support for tracing of MCDI (Management-Controller-to-
+ Driver-Interface) commands and responses, allowing debugging of
+ driver/firmware interaction.
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
index 882117a..2e8e5de 100644
--- a/drivers/net/ethernet/sfc/ef10.c
+++ b/drivers/net/ethernet/sfc/ef10.c
@@ -219,6 +219,9 @@ static int efx_ef10_probe(struct efx_nic *efx)
return -ENOMEM;
efx->nic_data = nic_data;
+ /* we assume later that we can copy from this buffer in dwords */
+ BUILD_BUG_ON(MCDI_CTL_SDU_LEN_MAX_V2 % 4);
+
rc = efx_nic_alloc_buffer(efx, &nic_data->mcdi_buf,
8 + MCDI_CTL_SDU_LEN_MAX_V2, GFP_KERNEL);
if (rc)
diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c
index b44ee31..1400ed4 100644
--- a/drivers/net/ethernet/sfc/mcdi.c
+++ b/drivers/net/ethernet/sfc/mcdi.c
@@ -58,14 +58,20 @@ int efx_mcdi_init(struct efx_nic *efx)
{
struct efx_mcdi_iface *mcdi;
bool already_attached;
- int rc;
+ int rc = -ENOMEM;
efx->mcdi = kzalloc(sizeof(*efx->mcdi), GFP_KERNEL);
if (!efx->mcdi)
- return -ENOMEM;
+ goto fail;
mcdi = efx_mcdi(efx);
mcdi->efx = efx;
+#ifdef CONFIG_SFC_MCDI_LOGGING
+ /* consuming code assumes buffer is page-sized */
+ mcdi->logging_buffer = (char *)__get_free_page(GFP_KERNEL);
+ if (!mcdi->logging_buffer)
+ goto fail1;
+#endif
init_waitqueue_head(&mcdi->wq);
spin_lock_init(&mcdi->iface_lock);
mcdi->state = MCDI_STATE_QUIESCENT;
@@ -81,7 +87,7 @@ int efx_mcdi_init(struct efx_nic *efx)
/* Recover from a failed assertion before probing */
rc = efx_mcdi_handle_assertion(efx);
if (rc)
- return rc;
+ goto fail2;
/* Let the MC (and BMC, if this is a LOM) know that the driver
* is loaded. We should do this before we reset the NIC.
@@ -90,7 +96,7 @@ int efx_mcdi_init(struct efx_nic *efx)
if (rc) {
netif_err(efx, probe, efx->net_dev,
"Unable to register driver with MCPU\n");
- return rc;
+ goto fail2;
}
if (already_attached)
/* Not a fatal error */
@@ -102,6 +108,15 @@ int efx_mcdi_init(struct efx_nic *efx)
efx->primary = efx;
return 0;
+fail2:
+#ifdef CONFIG_SFC_MCDI_LOGGING
+ free_page((unsigned long)mcdi->logging_buffer);
+fail1:
+#endif
+ kfree(efx->mcdi);
+ efx->mcdi = NULL;
+fail:
+ return rc;
}
void efx_mcdi_fini(struct efx_nic *efx)
@@ -114,6 +129,10 @@ void efx_mcdi_fini(struct efx_nic *efx)
/* Relinquish the device (back to the BMC, if this is a LOM) */
efx_mcdi_drv_attach(efx, false, NULL);
+#ifdef CONFIG_SFC_MCDI_LOGGING
+ free_page((unsigned long)efx->mcdi->iface.logging_buffer);
+#endif
+
kfree(efx->mcdi);
}
@@ -121,6 +140,9 @@ static void efx_mcdi_send_request(struct efx_nic *efx, unsigned cmd,
const efx_dword_t *inbuf, size_t inlen)
{
struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
+#ifdef CONFIG_SFC_MCDI_LOGGING
+ char *buf = mcdi->logging_buffer; /* page-sized */
+#endif
efx_dword_t hdr[2];
size_t hdr_len;
u32 xflags, seqno;
@@ -165,6 +187,31 @@ static void efx_mcdi_send_request(struct efx_nic *efx, unsigned cmd,
hdr_len = 8;
}
+#ifdef CONFIG_SFC_MCDI_LOGGING
+ if (!WARN_ON_ONCE(!buf)) {
+ int bytes = 0;
+ int i;
+ /* Lengths should always be a whole number of dwords, so scream
+ * if they're not.
+ */
+ WARN_ON_ONCE(hdr_len % 4);
+ WARN_ON_ONCE(inlen % 4);
+
+ /* We own the logging buffer, as only one MCDI can be in
+ * progress on a NIC at any one time. So no need for locking.
+ */
+ for (i = 0; i < hdr_len / 4 && bytes < PAGE_SIZE; i++)
+ bytes += snprintf(buf + bytes, PAGE_SIZE - bytes,
+ " %08x", le32_to_cpu(hdr[i].u32[0]));
+
+ for (i = 0; i < inlen / 4 && bytes < PAGE_SIZE; i++)
+ bytes += snprintf(buf + bytes, PAGE_SIZE - bytes,
+ " %08x", le32_to_cpu(inbuf[i].u32[0]));
+
+ netif_info(efx, hw, efx->net_dev, "MCDI RPC REQ:%s\n", buf);
+ }
+#endif
+
efx->type->mcdi_request(efx, hdr, hdr_len, inbuf, inlen);
mcdi->new_epoch = false;
@@ -206,6 +253,9 @@ static void efx_mcdi_read_response_header(struct efx_nic *efx)
{
struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
unsigned int respseq, respcmd, error;
+#ifdef CONFIG_SFC_MCDI_LOGGING
+ char *buf = mcdi->logging_buffer; /* page-sized */
+#endif
efx_dword_t hdr;
efx->type->mcdi_read_response(efx, &hdr, 0, 4);
@@ -223,6 +273,39 @@ static void efx_mcdi_read_response_header(struct efx_nic *efx)
EFX_DWORD_FIELD(hdr, MC_CMD_V2_EXTN_IN_ACTUAL_LEN);
}
+#ifdef CONFIG_SFC_MCDI_LOGGING
+ if (!WARN_ON_ONCE(!buf)) {
+ size_t hdr_len, data_len;
+ int bytes = 0;
+ int i;
+
+ WARN_ON_ONCE(mcdi->resp_hdr_len % 4);
+ hdr_len = mcdi->resp_hdr_len / 4;
+ /* MCDI_DECLARE_BUF ensures that underlying buffer is padded
+ * to dword size, and the MCDI buffer is always dword size
+ */
+ data_len = DIV_ROUND_UP(mcdi->resp_data_len, 4);
+
+ /* We own the logging buffer, as only one MCDI can be in
+ * progress on a NIC at any one time. So no need for locking.
+ */
+ for (i = 0; i < hdr_len && bytes < PAGE_SIZE; i++) {
+ efx->type->mcdi_read_response(efx, &hdr, (i * 4), 4);
+ bytes += snprintf(buf + bytes, PAGE_SIZE - bytes,
+ " %08x", le32_to_cpu(hdr.u32[0]));
+ }
+
+ for (i = 0; i < data_len && bytes < PAGE_SIZE; i++) {
+ efx->type->mcdi_read_response(efx, &hdr,
+ mcdi->resp_hdr_len + (i * 4), 4);
+ bytes += snprintf(buf + bytes, PAGE_SIZE - bytes,
+ " %08x", le32_to_cpu(hdr.u32[0]));
+ }
+
+ netif_info(efx, hw, efx->net_dev, "MCDI RPC RESP:%s\n", buf);
+ }
+#endif
+
if (error && mcdi->resp_data_len == 0) {
netif_err(efx, hw, efx->net_dev, "MC rebooted\n");
mcdi->resprc = -EIO;
diff --git a/drivers/net/ethernet/sfc/mcdi.h b/drivers/net/ethernet/sfc/mcdi.h
index 5df1e98..2f6f032 100644
--- a/drivers/net/ethernet/sfc/mcdi.h
+++ b/drivers/net/ethernet/sfc/mcdi.h
@@ -58,6 +58,7 @@ enum efx_mcdi_mode {
* enabled
* @async_list: Queue of asynchronous requests
* @async_timer: Timer for asynchronous request timeout
+ * @logging_buffer: buffer that may be used to build MCDI tracing messages
*/
struct efx_mcdi_iface {
struct efx_nic *efx;
@@ -74,6 +75,9 @@ struct efx_mcdi_iface {
spinlock_t async_lock;
struct list_head async_list;
struct timer_list async_timer;
+#ifdef CONFIG_SFC_MCDI_LOGGING
+ char *logging_buffer;
+#endif
};
struct efx_mcdi_mon {
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH net-next 2/4] sfc: add sysfs entry to control MCDI tracing
2015-05-20 15:49 [PATCH net-next v2 0/4] sfc: add MCDI tracing Edward Cree
2015-05-20 15:49 ` [PATCH net-next 1/4] sfc: add tracing of MCDI commands Edward Cree
@ 2015-05-20 15:50 ` Edward Cree
2015-05-20 15:50 ` [PATCH net-next 3/4] sfc: add module parameter to enable MCDI logging on new functions Edward Cree
` (2 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Edward Cree @ 2015-05-20 15:50 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
MCDI tracing is enabled per-function with a sysfs file
/sys/class/net/<NET_DEV>/device/mcdi_logging
Signed-off-by: Edward Cree <ecree@solarflare.com>
---
drivers/net/ethernet/sfc/Kconfig | 3 ++-
drivers/net/ethernet/sfc/efx.c | 49 ++++++++++++++++++++++++++++++++++------
drivers/net/ethernet/sfc/mcdi.c | 4 ++--
drivers/net/ethernet/sfc/mcdi.h | 2 ++
4 files changed, 48 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/sfc/Kconfig b/drivers/net/ethernet/sfc/Kconfig
index c4ba42b..4dd92b7 100644
--- a/drivers/net/ethernet/sfc/Kconfig
+++ b/drivers/net/ethernet/sfc/Kconfig
@@ -43,4 +43,5 @@ config SFC_MCDI_LOGGING
---help---
This enables support for tracing of MCDI (Management-Controller-to-
Driver-Interface) commands and responses, allowing debugging of
- driver/firmware interaction.
+ driver/firmware interaction. The tracing is actually enabled by
+ a sysfs file 'mcdi_logging' under the PCI device.
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 0f127a0..86a2da5 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -2298,6 +2298,28 @@ show_phy_type(struct device *dev, struct device_attribute *attr, char *buf)
}
static DEVICE_ATTR(phy_type, 0444, show_phy_type, NULL);
+#ifdef CONFIG_SFC_MCDI_LOGGING
+static ssize_t show_mcdi_log(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
+ struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
+
+ return scnprintf(buf, PAGE_SIZE, "%d\n", mcdi->logging_enabled);
+}
+static ssize_t set_mcdi_log(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
+ struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
+ bool enable = count > 0 && *buf != '0';
+
+ mcdi->logging_enabled = enable;
+ return count;
+}
+static DEVICE_ATTR(mcdi_logging, 0644, show_mcdi_log, set_mcdi_log);
+#endif
+
static int efx_register_netdev(struct efx_nic *efx)
{
struct net_device *net_dev = efx->net_dev;
@@ -2355,9 +2377,21 @@ static int efx_register_netdev(struct efx_nic *efx)
"failed to init net dev attributes\n");
goto fail_registered;
}
+#ifdef CONFIG_SFC_MCDI_LOGGING
+ rc = device_create_file(&efx->pci_dev->dev, &dev_attr_mcdi_logging);
+ if (rc) {
+ netif_err(efx, drv, efx->net_dev,
+ "failed to init net dev attributes\n");
+ goto fail_attr_mcdi_logging;
+ }
+#endif
return 0;
+#ifdef CONFIG_SFC_MCDI_LOGGING
+fail_attr_mcdi_logging:
+ device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_type);
+#endif
fail_registered:
rtnl_lock();
efx_dissociate(efx);
@@ -2376,13 +2410,14 @@ static void efx_unregister_netdev(struct efx_nic *efx)
BUG_ON(netdev_priv(efx->net_dev) != efx);
- strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name));
- device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_type);
-
- rtnl_lock();
- unregister_netdevice(efx->net_dev);
- efx->state = STATE_UNINIT;
- rtnl_unlock();
+ if (efx_dev_registered(efx)) {
+ strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name));
+#ifdef CONFIG_SFC_MCDI_LOGGING
+ device_remove_file(&efx->pci_dev->dev, &dev_attr_mcdi_logging);
+#endif
+ device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_type);
+ unregister_netdev(efx->net_dev);
+ }
}
/**************************************************************************
diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c
index 1400ed4..3e4137c 100644
--- a/drivers/net/ethernet/sfc/mcdi.c
+++ b/drivers/net/ethernet/sfc/mcdi.c
@@ -188,7 +188,7 @@ static void efx_mcdi_send_request(struct efx_nic *efx, unsigned cmd,
}
#ifdef CONFIG_SFC_MCDI_LOGGING
- if (!WARN_ON_ONCE(!buf)) {
+ if (mcdi->logging_enabled && !WARN_ON_ONCE(!buf)) {
int bytes = 0;
int i;
/* Lengths should always be a whole number of dwords, so scream
@@ -274,7 +274,7 @@ static void efx_mcdi_read_response_header(struct efx_nic *efx)
}
#ifdef CONFIG_SFC_MCDI_LOGGING
- if (!WARN_ON_ONCE(!buf)) {
+ if (mcdi->logging_enabled && !WARN_ON_ONCE(!buf)) {
size_t hdr_len, data_len;
int bytes = 0;
int i;
diff --git a/drivers/net/ethernet/sfc/mcdi.h b/drivers/net/ethernet/sfc/mcdi.h
index 2f6f032..47035a0 100644
--- a/drivers/net/ethernet/sfc/mcdi.h
+++ b/drivers/net/ethernet/sfc/mcdi.h
@@ -59,6 +59,7 @@ enum efx_mcdi_mode {
* @async_list: Queue of asynchronous requests
* @async_timer: Timer for asynchronous request timeout
* @logging_buffer: buffer that may be used to build MCDI tracing messages
+ * @logging_enabled: whether to trace MCDI
*/
struct efx_mcdi_iface {
struct efx_nic *efx;
@@ -77,6 +78,7 @@ struct efx_mcdi_iface {
struct timer_list async_timer;
#ifdef CONFIG_SFC_MCDI_LOGGING
char *logging_buffer;
+ bool logging_enabled;
#endif
};
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH net-next 3/4] sfc: add module parameter to enable MCDI logging on new functions
2015-05-20 15:49 [PATCH net-next v2 0/4] sfc: add MCDI tracing Edward Cree
2015-05-20 15:49 ` [PATCH net-next 1/4] sfc: add tracing of MCDI commands Edward Cree
2015-05-20 15:50 ` [PATCH net-next 2/4] sfc: add sysfs entry to control MCDI tracing Edward Cree
@ 2015-05-20 15:50 ` Edward Cree
2015-05-20 15:50 ` [PATCH net-next 4/4] sfc: Initialise MCDI buffers to 0 on declaration Edward Cree
2015-05-21 22:52 ` [PATCH net-next v2 0/4] sfc: add MCDI tracing David Miller
4 siblings, 0 replies; 8+ messages in thread
From: Edward Cree @ 2015-05-20 15:50 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
As many issues are encountered at probe time, where MCDI logging can't be
enabled through the sysfs node, this change adds a module parameter
'mcdi_logging_default', which defaults to false. When set to true, newly-
probed functions will have MCDI logging enabled. The setting can
subsequently be changed as normal through the sysfs node.
Signed-off-by: Edward Cree <ecree@solarflare.com>
---
drivers/net/ethernet/sfc/mcdi.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c
index 3e4137c..1f7153d 100644
--- a/drivers/net/ethernet/sfc/mcdi.c
+++ b/drivers/net/ethernet/sfc/mcdi.c
@@ -8,6 +8,7 @@
*/
#include <linux/delay.h>
+#include <linux/moduleparam.h>
#include <asm/cmpxchg.h>
#include "net_driver.h"
#include "nic.h"
@@ -54,6 +55,13 @@ static int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating,
static bool efx_mcdi_poll_once(struct efx_nic *efx);
static void efx_mcdi_abandon(struct efx_nic *efx);
+#ifdef CONFIG_SFC_MCDI_LOGGING
+static bool mcdi_logging_default;
+module_param(mcdi_logging_default, bool, 0644);
+MODULE_PARM_DESC(mcdi_logging_default,
+ "Enable MCDI logging on newly-probed functions");
+#endif
+
int efx_mcdi_init(struct efx_nic *efx)
{
struct efx_mcdi_iface *mcdi;
@@ -71,6 +79,7 @@ int efx_mcdi_init(struct efx_nic *efx)
mcdi->logging_buffer = (char *)__get_free_page(GFP_KERNEL);
if (!mcdi->logging_buffer)
goto fail1;
+ mcdi->logging_enabled = mcdi_logging_default;
#endif
init_waitqueue_head(&mcdi->wq);
spin_lock_init(&mcdi->iface_lock);
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH net-next 4/4] sfc: Initialise MCDI buffers to 0 on declaration.
2015-05-20 15:49 [PATCH net-next v2 0/4] sfc: add MCDI tracing Edward Cree
` (2 preceding siblings ...)
2015-05-20 15:50 ` [PATCH net-next 3/4] sfc: add module parameter to enable MCDI logging on new functions Edward Cree
@ 2015-05-20 15:50 ` Edward Cree
2015-05-21 22:52 ` [PATCH net-next v2 0/4] sfc: add MCDI tracing David Miller
4 siblings, 0 replies; 8+ messages in thread
From: Edward Cree @ 2015-05-20 15:50 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
From: Jon Cooper <jcooper@solarflare.com>
Signed-off-by: Edward Cree <ecree@solarflare.com>
---
drivers/net/ethernet/sfc/ef10.c | 24 +++++++++++++-----------
drivers/net/ethernet/sfc/mcdi.c | 8 ++++----
drivers/net/ethernet/sfc/mcdi.h | 8 +++++---
drivers/net/ethernet/sfc/ptp.c | 6 +++---
4 files changed, 25 insertions(+), 21 deletions(-)
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
index 2e8e5de..ed0ec88 100644
--- a/drivers/net/ethernet/sfc/ef10.c
+++ b/drivers/net/ethernet/sfc/ef10.c
@@ -350,7 +350,7 @@ static int efx_ef10_probe_vf(struct efx_nic *efx __attribute__ ((unused)))
static int efx_ef10_free_vis(struct efx_nic *efx)
{
- MCDI_DECLARE_BUF_OUT_OR_ERR(outbuf, 0);
+ MCDI_DECLARE_BUF_ERR(outbuf);
size_t outlen;
int rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FREE_VIS, NULL, 0,
outbuf, sizeof(outbuf), &outlen);
@@ -421,7 +421,7 @@ static int efx_ef10_alloc_piobufs(struct efx_nic *efx, unsigned int n)
static int efx_ef10_link_piobufs(struct efx_nic *efx)
{
struct efx_ef10_nic_data *nic_data = efx->nic_data;
- MCDI_DECLARE_BUF(inbuf,
+ _MCDI_DECLARE_BUF(inbuf,
max(MC_CMD_LINK_PIOBUF_IN_LEN,
MC_CMD_UNLINK_PIOBUF_IN_LEN));
struct efx_channel *channel;
@@ -432,6 +432,8 @@ static int efx_ef10_link_piobufs(struct efx_nic *efx)
BUILD_BUG_ON(MC_CMD_LINK_PIOBUF_OUT_LEN != 0);
BUILD_BUG_ON(MC_CMD_UNLINK_PIOBUF_OUT_LEN != 0);
+ memset(inbuf, 0, sizeof(inbuf));
+
/* Link a buffer to each VI in the write-combining mapping */
for (index = 0; index < nic_data->n_piobufs; ++index) {
MCDI_SET_DWORD(inbuf, LINK_PIOBUF_IN_PIOBUF_HANDLE,
@@ -1315,17 +1317,17 @@ static void efx_ef10_tx_init(struct efx_tx_queue *tx_queue)
{
MCDI_DECLARE_BUF(inbuf, MC_CMD_INIT_TXQ_IN_LEN(EFX_MAX_DMAQ_SIZE * 8 /
EFX_BUF_SIZE));
- MCDI_DECLARE_BUF(outbuf, MC_CMD_INIT_TXQ_OUT_LEN);
bool csum_offload = tx_queue->queue & EFX_TXQ_TYPE_OFFLOAD;
size_t entries = tx_queue->txd.buf.len / EFX_BUF_SIZE;
struct efx_channel *channel = tx_queue->channel;
struct efx_nic *efx = tx_queue->efx;
struct efx_ef10_nic_data *nic_data = efx->nic_data;
- size_t inlen, outlen;
+ size_t inlen;
dma_addr_t dma_addr;
efx_qword_t *txd;
int rc;
int i;
+ BUILD_BUG_ON(MC_CMD_INIT_TXQ_OUT_LEN != 0);
MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_SIZE, tx_queue->ptr_mask + 1);
MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_TARGET_EVQ, channel->channel);
@@ -1350,7 +1352,7 @@ static void efx_ef10_tx_init(struct efx_tx_queue *tx_queue)
inlen = MC_CMD_INIT_TXQ_IN_LEN(entries);
rc = efx_mcdi_rpc(efx, MC_CMD_INIT_TXQ, inbuf, inlen,
- outbuf, sizeof(outbuf), &outlen);
+ NULL, 0, NULL);
if (rc)
goto fail;
@@ -1383,7 +1385,7 @@ fail:
static void efx_ef10_tx_fini(struct efx_tx_queue *tx_queue)
{
MCDI_DECLARE_BUF(inbuf, MC_CMD_FINI_TXQ_IN_LEN);
- MCDI_DECLARE_BUF(outbuf, MC_CMD_FINI_TXQ_OUT_LEN);
+ MCDI_DECLARE_BUF_ERR(outbuf);
struct efx_nic *efx = tx_queue->efx;
size_t outlen;
int rc;
@@ -1690,15 +1692,15 @@ static void efx_ef10_rx_init(struct efx_rx_queue *rx_queue)
MCDI_DECLARE_BUF(inbuf,
MC_CMD_INIT_RXQ_IN_LEN(EFX_MAX_DMAQ_SIZE * 8 /
EFX_BUF_SIZE));
- MCDI_DECLARE_BUF(outbuf, MC_CMD_INIT_RXQ_OUT_LEN);
struct efx_channel *channel = efx_rx_queue_channel(rx_queue);
size_t entries = rx_queue->rxd.buf.len / EFX_BUF_SIZE;
struct efx_nic *efx = rx_queue->efx;
struct efx_ef10_nic_data *nic_data = efx->nic_data;
- size_t inlen, outlen;
+ size_t inlen;
dma_addr_t dma_addr;
int rc;
int i;
+ BUILD_BUG_ON(MC_CMD_INIT_RXQ_OUT_LEN != 0);
rx_queue->scatter_n = 0;
rx_queue->scatter_len = 0;
@@ -1727,7 +1729,7 @@ static void efx_ef10_rx_init(struct efx_rx_queue *rx_queue)
inlen = MC_CMD_INIT_RXQ_IN_LEN(entries);
rc = efx_mcdi_rpc(efx, MC_CMD_INIT_RXQ, inbuf, inlen,
- outbuf, sizeof(outbuf), &outlen);
+ NULL, 0, NULL);
if (rc)
netdev_WARN(efx->net_dev, "failed to initialise RXQ %d\n",
efx_rx_queue_index(rx_queue));
@@ -1736,7 +1738,7 @@ static void efx_ef10_rx_init(struct efx_rx_queue *rx_queue)
static void efx_ef10_rx_fini(struct efx_rx_queue *rx_queue)
{
MCDI_DECLARE_BUF(inbuf, MC_CMD_FINI_RXQ_IN_LEN);
- MCDI_DECLARE_BUF(outbuf, MC_CMD_FINI_RXQ_OUT_LEN);
+ MCDI_DECLARE_BUF_ERR(outbuf);
struct efx_nic *efx = rx_queue->efx;
size_t outlen;
int rc;
@@ -1898,7 +1900,7 @@ static int efx_ef10_ev_init(struct efx_channel *channel)
static void efx_ef10_ev_fini(struct efx_channel *channel)
{
MCDI_DECLARE_BUF(inbuf, MC_CMD_FINI_EVQ_IN_LEN);
- MCDI_DECLARE_BUF(outbuf, MC_CMD_FINI_EVQ_OUT_LEN);
+ MCDI_DECLARE_BUF_ERR(outbuf);
struct efx_nic *efx = channel->efx;
size_t outlen;
int rc;
diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c
index 1f7153d..612f3752 100644
--- a/drivers/net/ethernet/sfc/mcdi.c
+++ b/drivers/net/ethernet/sfc/mcdi.c
@@ -498,7 +498,7 @@ static bool efx_mcdi_complete_async(struct efx_mcdi_iface *mcdi, bool timeout)
struct efx_mcdi_async_param *async;
size_t hdr_len, data_len, err_len;
efx_dword_t *outbuf;
- MCDI_DECLARE_BUF_OUT_OR_ERR(errbuf, 0);
+ MCDI_DECLARE_BUF_ERR(errbuf);
int rc;
if (cmpxchg(&mcdi->state,
@@ -626,7 +626,7 @@ static int _efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen,
size_t *outlen_actual, bool quiet)
{
struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
- MCDI_DECLARE_BUF_OUT_OR_ERR(errbuf, 0);
+ MCDI_DECLARE_BUF_ERR(errbuf);
int rc;
if (mcdi->mode == MCDI_MODE_POLL)
@@ -1481,7 +1481,7 @@ fail1:
static int efx_mcdi_read_assertion(struct efx_nic *efx)
{
MCDI_DECLARE_BUF(inbuf, MC_CMD_GET_ASSERTS_IN_LEN);
- MCDI_DECLARE_BUF_OUT_OR_ERR(outbuf, MC_CMD_GET_ASSERTS_OUT_LEN);
+ MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_ASSERTS_OUT_LEN);
unsigned int flags, index;
const char *reason;
size_t outlen;
@@ -1791,7 +1791,7 @@ int efx_mcdi_set_workaround(struct efx_nic *efx, u32 type, bool enabled)
int efx_mcdi_get_workarounds(struct efx_nic *efx, unsigned int *impl_out,
unsigned int *enabled_out)
{
- MCDI_DECLARE_BUF_OUT_OR_ERR(outbuf, MC_CMD_GET_WORKAROUNDS_OUT_LEN);
+ MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_WORKAROUNDS_OUT_LEN);
size_t outlen;
int rc;
diff --git a/drivers/net/ethernet/sfc/mcdi.h b/drivers/net/ethernet/sfc/mcdi.h
index 47035a0..1838afe 100644
--- a/drivers/net/ethernet/sfc/mcdi.h
+++ b/drivers/net/ethernet/sfc/mcdi.h
@@ -182,10 +182,12 @@ void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev);
* 32-bit-aligned. Also, on Siena we must copy to the MC shared
* memory strictly 32 bits at a time, so add any necessary padding.
*/
-#define MCDI_DECLARE_BUF(_name, _len) \
+#define _MCDI_DECLARE_BUF(_name, _len) \
efx_dword_t _name[DIV_ROUND_UP(_len, 4)]
-#define MCDI_DECLARE_BUF_OUT_OR_ERR(_name, _len) \
- MCDI_DECLARE_BUF(_name, max_t(size_t, _len, 8))
+#define MCDI_DECLARE_BUF(_name, _len) \
+ _MCDI_DECLARE_BUF(_name, _len) = {{{0}}}
+#define MCDI_DECLARE_BUF_ERR(_name) \
+ MCDI_DECLARE_BUF(_name, 8)
#define _MCDI_PTR(_buf, _offset) \
((u8 *)(_buf) + (_offset))
#define MCDI_PTR(_buf, _field) \
diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c
index 5578c54..ad62615 100644
--- a/drivers/net/ethernet/sfc/ptp.c
+++ b/drivers/net/ethernet/sfc/ptp.c
@@ -306,7 +306,7 @@ struct efx_ptp_data {
struct work_struct pps_work;
struct workqueue_struct *pps_workwq;
bool nic_ts_enabled;
- MCDI_DECLARE_BUF(txbuf, MC_CMD_PTP_IN_TRANSMIT_LENMAX);
+ _MCDI_DECLARE_BUF(txbuf, MC_CMD_PTP_IN_TRANSMIT_LENMAX);
unsigned int good_syncs;
unsigned int fast_syncs;
@@ -573,7 +573,7 @@ static int efx_ptp_get_timestamp_corrections(struct efx_nic *efx)
static int efx_ptp_enable(struct efx_nic *efx)
{
MCDI_DECLARE_BUF(inbuf, MC_CMD_PTP_IN_ENABLE_LEN);
- MCDI_DECLARE_BUF_OUT_OR_ERR(outbuf, 0);
+ MCDI_DECLARE_BUF_ERR(outbuf);
int rc;
MCDI_SET_DWORD(inbuf, PTP_IN_OP, MC_CMD_PTP_OP_ENABLE);
@@ -601,7 +601,7 @@ static int efx_ptp_enable(struct efx_nic *efx)
static int efx_ptp_disable(struct efx_nic *efx)
{
MCDI_DECLARE_BUF(inbuf, MC_CMD_PTP_IN_DISABLE_LEN);
- MCDI_DECLARE_BUF_OUT_OR_ERR(outbuf, 0);
+ MCDI_DECLARE_BUF_ERR(outbuf);
int rc;
MCDI_SET_DWORD(inbuf, PTP_IN_OP, MC_CMD_PTP_OP_DISABLE);
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH net-next v2 0/4] sfc: add MCDI tracing
2015-05-20 15:49 [PATCH net-next v2 0/4] sfc: add MCDI tracing Edward Cree
` (3 preceding siblings ...)
2015-05-20 15:50 ` [PATCH net-next 4/4] sfc: Initialise MCDI buffers to 0 on declaration Edward Cree
@ 2015-05-21 22:52 ` David Miller
2015-05-22 14:49 ` Edward Cree
4 siblings, 1 reply; 8+ messages in thread
From: David Miller @ 2015-05-21 22:52 UTC (permalink / raw)
To: ecree; +Cc: netdev, linux-net-drivers
From: Edward Cree <ecree@solarflare.com>
Date: Wed, 20 May 2015 16:49:09 +0100
> This patchset adds support for logging MCDI (Management-Controller-to-
> Driver Interface) interactions between the sfc driver and a bound device,
> to aid in debugging.
> Solarflare has a tool to decode the resulting traces and will look to
> open-source this if there is any external interest, but the protocol is
> already detailed in drivers/net/ethernet/sfc/mcdi_pcol.h.
>
> v2: avoid long lines in cover letter; fix multiline comment style
All of this work to allocate the buffer, add messages to it, and dump it
to some user obtainable location duplicates existing infrastructure in
the kernel.
Please do not do this, and instead use the kernel's existing tracing
infrastructure to implement this.
I do not care how much time and effort you've already invested in your
existing tool, you should have thought about that when designing this
in the first place.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next v2 0/4] sfc: add MCDI tracing
2015-05-21 22:52 ` [PATCH net-next v2 0/4] sfc: add MCDI tracing David Miller
@ 2015-05-22 14:49 ` Edward Cree
2015-05-22 19:03 ` David Miller
0 siblings, 1 reply; 8+ messages in thread
From: Edward Cree @ 2015-05-22 14:49 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
On 21/05/15 23:52, David Miller wrote:
> All of this work to allocate the buffer, add messages to it, and dump it
> to some user obtainable location duplicates existing infrastructure in
> the kernel.
> Please do not do this, and instead use the kernel's existing tracing
> infrastructure to implement this.
The logging_buffer we allocate isn't there to store _messages_ for later
dumping, it's a work area for constructing a _single_ message, which is
then merely written to the system log with netif_info. Thus, I don't see
how it would make much difference if we used (say) ftrace instead of
netif_info to ship the events to userspace.
The reason the buffer is long-lived is simply to avoid the overhead of
allocating and freeing it every MCDI call, since MCDIs are already known
to be serialised for other reasons.
Can you please further explain your objection and what you'd prefer us to
do?
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next v2 0/4] sfc: add MCDI tracing
2015-05-22 14:49 ` Edward Cree
@ 2015-05-22 19:03 ` David Miller
0 siblings, 0 replies; 8+ messages in thread
From: David Miller @ 2015-05-22 19:03 UTC (permalink / raw)
To: ecree; +Cc: netdev, linux-net-drivers
From: Edward Cree <ecree@solarflare.com>
Date: Fri, 22 May 2015 15:49:46 +0100
> On 21/05/15 23:52, David Miller wrote:
>> All of this work to allocate the buffer, add messages to it, and dump it
>> to some user obtainable location duplicates existing infrastructure in
>> the kernel.
>> Please do not do this, and instead use the kernel's existing tracing
>> infrastructure to implement this.
>
> The logging_buffer we allocate isn't there to store _messages_ for later
> dumping, it's a work area for constructing a _single_ message, which is
> then merely written to the system log with netif_info. Thus, I don't see
> how it would make much difference if we used (say) ftrace instead of
> netif_info to ship the events to userspace.
> The reason the buffer is long-lived is simply to avoid the overhead of
> allocating and freeing it every MCDI call, since MCDIs are already known
> to be serialised for other reasons.
> Can you please further explain your objection and what you'd prefer us to
> do?
Ok fair enough, please repost your series, thanks.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2015-05-22 19:03 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-20 15:49 [PATCH net-next v2 0/4] sfc: add MCDI tracing Edward Cree
2015-05-20 15:49 ` [PATCH net-next 1/4] sfc: add tracing of MCDI commands Edward Cree
2015-05-20 15:50 ` [PATCH net-next 2/4] sfc: add sysfs entry to control MCDI tracing Edward Cree
2015-05-20 15:50 ` [PATCH net-next 3/4] sfc: add module parameter to enable MCDI logging on new functions Edward Cree
2015-05-20 15:50 ` [PATCH net-next 4/4] sfc: Initialise MCDI buffers to 0 on declaration Edward Cree
2015-05-21 22:52 ` [PATCH net-next v2 0/4] sfc: add MCDI tracing David Miller
2015-05-22 14:49 ` Edward Cree
2015-05-22 19:03 ` David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).