[v2,17/29] net/ena: add support for large LLQ headers
diff mbox series

Message ID 20200401142127.13715-18-mk@semihalf.com
State Superseded, archived
Delegated to: Ferruh Yigit
Headers show
Series
  • Update ENA driver to v2.1.0
Related show

Checks

Context Check Description
ci/Intel-compilation success Compilation OK
ci/checkpatch warning coding style issues

Commit Message

Michał Krawczyk April 1, 2020, 2:21 p.m. UTC
If the device supports larger LLQ (Low Latency Queue) headers, the user
can activate them by enabling CONFIG_RTE_LIBRTE_ENA_LARGE_LLQ_HEADERS
flag in the configuration file.

If the device isn't supporting this feature, the default value will be
used.

Signed-off-by: Michal Krawczyk <mk@semihalf.com>
Reviewed-by: Igor Chauskin <igorch@amazon.com>
Reviewed-by: Guy Tzalik <gtzalik@amazon.com>
---
v2:
  * Use devargs instead of compilation options

 doc/guides/nics/ena.rst      |   8 +++
 drivers/net/ena/ena_ethdev.c | 110 +++++++++++++++++++++++++++++++++--
 drivers/net/ena/ena_ethdev.h |   2 +
 3 files changed, 114 insertions(+), 6 deletions(-)

Comments

Ferruh Yigit April 2, 2020, 1:02 p.m. UTC | #1
On 4/1/2020 3:21 PM, Michal Krawczyk wrote:
> If the device supports larger LLQ (Low Latency Queue) headers, the user
> can activate them by enabling CONFIG_RTE_LIBRTE_ENA_LARGE_LLQ_HEADERS
> flag in the configuration file.
> 
> If the device isn't supporting this feature, the default value will be
> used.
> 
> Signed-off-by: Michal Krawczyk <mk@semihalf.com>
> Reviewed-by: Igor Chauskin <igorch@amazon.com>
> Reviewed-by: Guy Tzalik <gtzalik@amazon.com>
> ---
> v2:
>   * Use devargs instead of compilation options
> 
>  doc/guides/nics/ena.rst      |   8 +++
>  drivers/net/ena/ena_ethdev.c | 110 +++++++++++++++++++++++++++++++++--
>  drivers/net/ena/ena_ethdev.h |   2 +
>  3 files changed, 114 insertions(+), 6 deletions(-)
> 
> diff --git a/doc/guides/nics/ena.rst b/doc/guides/nics/ena.rst
> index bbf27f235a..d5081e91e5 100644
> --- a/doc/guides/nics/ena.rst
> +++ b/doc/guides/nics/ena.rst
> @@ -95,6 +95,14 @@ Configuration information
>     * **CONFIG_RTE_LIBRTE_ENA_COM_DEBUG** (default n): Enables or disables debug
>       logging of low level tx/rx logic in ena_com(base) within the ENA PMD driver.
>  
> +**Runtime Configuration Parameters**
> +
> +   * **large_llq_hdr** (default 0)
> +
> +     Enables or disables usage of large LLQ headers. This option will have
> +     effect only if the device also supports large LLQ headers. Otherwise, the
> +     default value will be used.

Again, better to describe what 'LLQ' is, and you may want to describe what is
the usage/benefit of enabling large LLQ headers, up to you.
Michał Krawczyk April 3, 2020, 12:15 p.m. UTC | #2
czw., 2 kwi 2020 o 15:02 Ferruh Yigit <ferruh.yigit@intel.com> napisał(a):
>
> On 4/1/2020 3:21 PM, Michal Krawczyk wrote:
> > If the device supports larger LLQ (Low Latency Queue) headers, the user
> > can activate them by enabling CONFIG_RTE_LIBRTE_ENA_LARGE_LLQ_HEADERS
> > flag in the configuration file.
> >
> > If the device isn't supporting this feature, the default value will be
> > used.
> >
> > Signed-off-by: Michal Krawczyk <mk@semihalf.com>
> > Reviewed-by: Igor Chauskin <igorch@amazon.com>
> > Reviewed-by: Guy Tzalik <gtzalik@amazon.com>
> > ---
> > v2:
> >   * Use devargs instead of compilation options
> >
> >  doc/guides/nics/ena.rst      |   8 +++
> >  drivers/net/ena/ena_ethdev.c | 110 +++++++++++++++++++++++++++++++++--
> >  drivers/net/ena/ena_ethdev.h |   2 +
> >  3 files changed, 114 insertions(+), 6 deletions(-)
> >
> > diff --git a/doc/guides/nics/ena.rst b/doc/guides/nics/ena.rst
> > index bbf27f235a..d5081e91e5 100644
> > --- a/doc/guides/nics/ena.rst
> > +++ b/doc/guides/nics/ena.rst
> > @@ -95,6 +95,14 @@ Configuration information
> >     * **CONFIG_RTE_LIBRTE_ENA_COM_DEBUG** (default n): Enables or disables debug
> >       logging of low level tx/rx logic in ena_com(base) within the ENA PMD driver.
> >
> > +**Runtime Configuration Parameters**
> > +
> > +   * **large_llq_hdr** (default 0)
> > +
> > +     Enables or disables usage of large LLQ headers. This option will have
> > +     effect only if the device also supports large LLQ headers. Otherwise, the
> > +     default value will be used.
>
> Again, better to describe what 'LLQ' is, and you may want to describe what is
> the usage/benefit of enabling large LLQ headers, up to you.

Sure, I will do that in v3. Moreover, the commit log needs an update,
as it's currently describing static configuration, while we're using
devargs now (introduced in v2).

Patch
diff mbox series

diff --git a/doc/guides/nics/ena.rst b/doc/guides/nics/ena.rst
index bbf27f235a..d5081e91e5 100644
--- a/doc/guides/nics/ena.rst
+++ b/doc/guides/nics/ena.rst
@@ -95,6 +95,14 @@  Configuration information
    * **CONFIG_RTE_LIBRTE_ENA_COM_DEBUG** (default n): Enables or disables debug
      logging of low level tx/rx logic in ena_com(base) within the ENA PMD driver.
 
+**Runtime Configuration Parameters**
+
+   * **large_llq_hdr** (default 0)
+
+     Enables or disables usage of large LLQ headers. This option will have
+     effect only if the device also supports large LLQ headers. Otherwise, the
+     default value will be used.
+
 **ENA Configuration Parameters**
 
    * **Number of Queues**
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index d5f700093f..f23efbe464 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -13,6 +13,7 @@ 
 #include <rte_errno.h>
 #include <rte_version.h>
 #include <rte_net.h>
+#include <rte_kvargs.h>
 
 #include "ena_ethdev.h"
 #include "ena_logs.h"
@@ -82,6 +83,9 @@  struct ena_stats {
 #define ENA_STAT_GLOBAL_ENTRY(stat) \
 	ENA_STAT_ENTRY(stat, dev)
 
+/* Device arguments */
+#define ENA_DEVARG_LARGE_LLQ_HDR "large_llq_hdr"
+
 /*
  * Each rte_memzone should have unique name.
  * To satisfy it, count number of allocation and add it to name.
@@ -231,6 +235,11 @@  static int ena_xstats_get_by_id(struct rte_eth_dev *dev,
 				const uint64_t *ids,
 				uint64_t *values,
 				unsigned int n);
+static int ena_process_bool_devarg(const char *key,
+				   const char *value,
+				   void *opaque);
+static int ena_parse_devargs(struct ena_adapter *adapter,
+			     struct rte_devargs *devargs);
 
 static const struct eth_dev_ops ena_dev_ops = {
 	.dev_configure        = ena_dev_configure,
@@ -842,7 +851,8 @@  static int ena_check_valid_conf(struct ena_adapter *adapter)
 }
 
 static int
-ena_calc_io_queue_size(struct ena_calc_queue_size_ctx *ctx)
+ena_calc_io_queue_size(struct ena_calc_queue_size_ctx *ctx,
+		       bool use_large_llq_hdr)
 {
 	struct ena_admin_feature_llq_desc *llq = &ctx->get_feat_ctx->llq;
 	struct ena_com_dev *ena_dev = ctx->ena_dev;
@@ -895,6 +905,21 @@  ena_calc_io_queue_size(struct ena_calc_queue_size_ctx *ctx)
 	max_rx_queue_size = rte_align32prevpow2(max_rx_queue_size);
 	max_tx_queue_size = rte_align32prevpow2(max_tx_queue_size);
 
+	if (use_large_llq_hdr) {
+		if ((llq->entry_size_ctrl_supported &
+		     ENA_ADMIN_LIST_ENTRY_SIZE_256B) &&
+		    (ena_dev->tx_mem_queue_type ==
+		     ENA_ADMIN_PLACEMENT_POLICY_DEV)) {
+			max_tx_queue_size /= 2;
+			PMD_INIT_LOG(INFO,
+				"Forcing large headers and decreasing maximum TX queue size to %d\n",
+				max_tx_queue_size);
+		} else {
+			PMD_INIT_LOG(ERR,
+				"Forcing large headers failed: LLQ is disabled or device does not support large headers\n");
+		}
+	}
+
 	if (unlikely(max_rx_queue_size == 0 || max_tx_queue_size == 0)) {
 		PMD_INIT_LOG(ERR, "Invalid queue size");
 		return -EFAULT;
@@ -1594,14 +1619,25 @@  static void ena_timer_wd_callback(__rte_unused struct rte_timer *timer,
 }
 
 static inline void
-set_default_llq_configurations(struct ena_llq_configurations *llq_config)
+set_default_llq_configurations(struct ena_llq_configurations *llq_config,
+			       struct ena_admin_feature_llq_desc *llq,
+			       bool use_large_llq_hdr)
 {
 	llq_config->llq_header_location = ENA_ADMIN_INLINE_HEADER;
-	llq_config->llq_ring_entry_size = ENA_ADMIN_LIST_ENTRY_SIZE_128B;
 	llq_config->llq_stride_ctrl = ENA_ADMIN_MULTIPLE_DESCS_PER_ENTRY;
 	llq_config->llq_num_decs_before_header =
 		ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_2;
-	llq_config->llq_ring_entry_size_value = 128;
+
+	if (use_large_llq_hdr &&
+	    (llq->entry_size_ctrl_supported & ENA_ADMIN_LIST_ENTRY_SIZE_256B)) {
+		llq_config->llq_ring_entry_size =
+			ENA_ADMIN_LIST_ENTRY_SIZE_256B;
+		llq_config->llq_ring_entry_size_value = 256;
+	} else {
+		llq_config->llq_ring_entry_size =
+			ENA_ADMIN_LIST_ENTRY_SIZE_128B;
+		llq_config->llq_ring_entry_size_value = 128;
+	}
 }
 
 static int
@@ -1740,6 +1776,12 @@  static int eth_ena_dev_init(struct rte_eth_dev *eth_dev)
 	snprintf(adapter->name, ENA_NAME_MAX_LEN, "ena_%d",
 		 adapter->id_number);
 
+	rc = ena_parse_devargs(adapter, pci_dev->device.devargs);
+	if (rc != 0) {
+		PMD_INIT_LOG(CRIT, "Failed to parse devargs\n");
+		goto err;
+	}
+
 	/* device specific initialization routine */
 	rc = ena_device_init(ena_dev, &get_feat_ctx, &wd_state);
 	if (rc) {
@@ -1748,7 +1790,8 @@  static int eth_ena_dev_init(struct rte_eth_dev *eth_dev)
 	}
 	adapter->wd_state = wd_state;
 
-	set_default_llq_configurations(&llq_config);
+	set_default_llq_configurations(&llq_config, &get_feat_ctx.llq,
+		adapter->use_large_llq_hdr);
 	rc = ena_set_queues_placement_policy(adapter, ena_dev,
 					     &get_feat_ctx.llq, &llq_config);
 	if (unlikely(rc)) {
@@ -1766,7 +1809,8 @@  static int eth_ena_dev_init(struct rte_eth_dev *eth_dev)
 	calc_queue_ctx.get_feat_ctx = &get_feat_ctx;
 
 	max_num_io_queues = ena_calc_max_io_queue_num(ena_dev, &get_feat_ctx);
-	rc = ena_calc_io_queue_size(&calc_queue_ctx);
+	rc = ena_calc_io_queue_size(&calc_queue_ctx,
+		adapter->use_large_llq_hdr);
 	if (unlikely((rc != 0) || (max_num_io_queues == 0))) {
 		rc = -EFAULT;
 		goto err_device_destroy;
@@ -2582,6 +2626,59 @@  static int ena_xstats_get_by_id(struct rte_eth_dev *dev,
 	return valid;
 }
 
+static int ena_process_bool_devarg(const char *key,
+				   const char *value,
+				   void *opaque)
+{
+	struct ena_adapter *adapter = opaque;
+	bool bool_value;
+
+	/* Parse the value. */
+	if (strcmp(value, "1") == 0) {
+		bool_value = true;
+	} else if (strcmp(value, "0") == 0) {
+		bool_value = false;
+	} else {
+		PMD_INIT_LOG(ERR,
+			"Invalid value: '%s' for key '%s'. Accepted: '0' or '1'\n",
+			value, key);
+		return -EINVAL;
+	}
+
+	/* Now, assign it to the proper adapter field. */
+	if (strcmp(key, ENA_DEVARG_LARGE_LLQ_HDR) == 0)
+		adapter->use_large_llq_hdr = bool_value;
+
+	return 0;
+}
+
+static int ena_parse_devargs(struct ena_adapter *adapter,
+			     struct rte_devargs *devargs)
+{
+	static const char * const allowed_args[] = {
+		ENA_DEVARG_LARGE_LLQ_HDR,
+	};
+	struct rte_kvargs *kvlist;
+	int rc;
+
+	if (devargs == NULL)
+		return 0;
+
+	kvlist = rte_kvargs_parse(devargs->args, allowed_args);
+	if (kvlist == NULL) {
+		PMD_INIT_LOG(ERR, "Invalid device arguments: %s\n",
+			devargs->args);
+		return -EINVAL;
+	}
+
+	rc = rte_kvargs_process(kvlist, ENA_DEVARG_LARGE_LLQ_HDR,
+		ena_process_bool_devarg, adapter);
+
+	rte_kvargs_free(kvlist);
+
+	return rc;
+}
+
 /*********************************************************************
  *  PMD configuration
  *********************************************************************/
@@ -2608,6 +2705,7 @@  static struct rte_pci_driver rte_ena_pmd = {
 RTE_PMD_REGISTER_PCI(net_ena, rte_ena_pmd);
 RTE_PMD_REGISTER_PCI_TABLE(net_ena, pci_id_ena_map);
 RTE_PMD_REGISTER_KMOD_DEP(net_ena, "* igb_uio | uio_pci_generic | vfio-pci");
+RTE_PMD_REGISTER_PARAM_STRING(net_ena, ENA_DEVARG_LARGE_LLQ_HDR "=<0|1>");
 
 RTE_INIT(ena_init_log)
 {
diff --git a/drivers/net/ena/ena_ethdev.h b/drivers/net/ena/ena_ethdev.h
index 99d1fba64d..0e82c894f4 100644
--- a/drivers/net/ena/ena_ethdev.h
+++ b/drivers/net/ena/ena_ethdev.h
@@ -200,6 +200,8 @@  struct ena_adapter {
 	bool trigger_reset;
 
 	bool wd_state;
+
+	bool use_large_llq_hdr;
 };
 
 #endif /* _ENA_ETHDEV_H_ */