From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id DC944A00C5; Thu, 15 Sep 2022 17:19:23 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id E96784021D; Thu, 15 Sep 2022 17:19:22 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by mails.dpdk.org (Postfix) with ESMTP id 6B60440156 for ; Thu, 15 Sep 2022 17:19:20 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1663255160; x=1694791160; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=4sD+4h0nxD+9cESxouCrDw3VwbeZ5LKeYQiviWeStTM=; b=DKbhYnmS5STI/zJUfYVkQg+oc24sUsdN7vYl9TPznZ5eB2iKcMr34m93 4E3a9fjtcXrjpynTK6AiIUWoLu+5QfKE4L+uAj5gf4mtA4w/TO+eRR4aS mmEzcsy5V/hOeqzLobScTvzzRCa5oucG94LP98myBMRPK6inRj3BgLNg5 ahHtla7d392qigiWeDtAIoSJGBw9rBQX23jR5X/EN0oix8V4+ngFsZ9Bp dUm/QS/muQZHJ/HQ5xO38gRyNCDf0QNHxk8osNB1Sqm2Ad4XD4TVy7Msv /ZkcNIAPp86ynsWhOwrEho7J6cxdkQC7IFWEI/wIjjl+/aaBLcV0ikEtF w==; X-IronPort-AV: E=McAfee;i="6500,9779,10471"; a="300103221" X-IronPort-AV: E=Sophos;i="5.93,318,1654585200"; d="scan'208";a="300103221" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Sep 2022 08:19:18 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.93,318,1654585200"; d="scan'208";a="679559419" Received: from txandevlnx322.an.intel.com ([10.123.117.44]) by fmsmga008.fm.intel.com with ESMTP; 15 Sep 2022 08:19:17 -0700 From: Naga Harish K S V To: jerinj@marvell.com, jay.jayatheerthan@intel.com Cc: dev@dpdk.org Subject: [PATCH v3 1/2] eventdev/eth_tx: add queue start stop API Date: Thu, 15 Sep 2022 10:19:14 -0500 Message-Id: <20220915151915.2285722-1-s.v.naga.harish.k@intel.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20220915095329.2217018-1-s.v.naga.harish.k@intel.com> References: <20220915095329.2217018-1-s.v.naga.harish.k@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add support to start or stop a particular queue that is associated with the adapter. Start function enables the Tx adapter to start enqueueing packets to the Tx queue. Stop function stops the Tx adapter from transmitting any packets to the Tx queue. The Tx adapter also frees any packets that may have been buffered for this queue. All inflight packets destined to the queue are freed by the adapter runtime until the queue is started again. Signed-off-by: Naga Harish K S V --- v3: * fix documentation and address review comments --- .../prog_guide/event_ethernet_tx_adapter.rst | 16 +++ doc/guides/rel_notes/release_22_11.rst | 8 ++ lib/eventdev/eventdev_pmd.h | 41 +++++++ lib/eventdev/rte_event_eth_tx_adapter.c | 113 +++++++++++++++++- lib/eventdev/rte_event_eth_tx_adapter.h | 42 +++++++ lib/eventdev/version.map | 2 + 6 files changed, 218 insertions(+), 4 deletions(-) diff --git a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst index 4da9bcda3a..8eb1548cd5 100644 --- a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst +++ b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst @@ -182,3 +182,19 @@ mbufs are destined to the same ethernet port and queue by setting the bit ``rte_event_vector::queue``. If ``rte_event_vector::attr_valid`` is not set then the Tx adapter should peek into each mbuf and transmit them to the requested ethernet port and queue pair. + +Queue start/stop +~~~~~~~~~~~~~~~~ + +The adapter can be configured to start/stop enqueueing of packets to a NIC +queue using ``rte_event_eth_tx_adapter_queue_start()`` or +``rte_event_eth_tx_adapter_queue_stop()`` respectively. By default the queue +is in start state. + +Start function enables the adapter runtime to start enqueueing packets +to the Tx queue. + +Stop function stops the adapter runtime function from enqueueing any +packets to the associated Tx queue. This API also frees any packets that +may have been buffered for this queue. All inflight packets destined to the +queue are freed by the adapter runtime until the queue is started again. diff --git a/doc/guides/rel_notes/release_22_11.rst b/doc/guides/rel_notes/release_22_11.rst index c32c18ff49..ec05ddcbf5 100644 --- a/doc/guides/rel_notes/release_22_11.rst +++ b/doc/guides/rel_notes/release_22_11.rst @@ -30,6 +30,14 @@ New Features Added ``rte_event_eth_tx_adapter_instance_get`` to get the Tx adapter instance id for specified ethernet device id and Tx queue index. + +* **Added Tx adapter queue start/stop API** + + Added ``rte_event_eth_tx_adapter_queue_start`` to start enqueueing packets to the Tx queue by + Tx adapter. + Added ``rte_event_eth_tx_adapter_queue_stop`` to stop the Tx Adapter from transmitting any + packets to the Tx queue. + .. This section should contain new features added in this release. Sample format: diff --git a/lib/eventdev/eventdev_pmd.h b/lib/eventdev/eventdev_pmd.h index f514a37575..31eaf927df 100644 --- a/lib/eventdev/eventdev_pmd.h +++ b/lib/eventdev/eventdev_pmd.h @@ -1294,6 +1294,43 @@ typedef int (*eventdev_eth_tx_adapter_stats_reset_t)(uint8_t id, typedef int (*eventdev_eth_tx_adapter_instance_get_t) (uint16_t eth_dev_id, uint16_t tx_queue_id, uint8_t *txa_inst_id); +/** + * Start a Tx queue that is assigned to Tx adapter instance + * + * @param id + * Adapter identifier + * + * @param eth_dev_id + * Port identifier of Ethernet device + * + * @param tx_queue_id + * Ethernet device Tx queue index + * + * @return + * - 0: Success + * - <0: Error code on failure + */ +typedef int (*eventdev_eth_tx_adapter_queue_start) + (uint8_t id, uint16_t eth_dev_id, uint16_t tx_queue_id); + +/** + * Stop a Tx queue that is assigned to Tx adapter instance + * + * @param id + * Adapter identifier + * + * @param eth_dev_id + * Port identifier of Ethernet device + * + * @param tx_queue_id + * Ethernet device Tx queue index + * + * @return + * - 0: Success + * - <0: Error code on failure + */ +typedef int (*eventdev_eth_tx_adapter_queue_stop) + (uint8_t id, uint16_t eth_dev_id, uint16_t tx_queue_id); /** Event device operations function pointer table */ struct eventdev_ops { @@ -1409,6 +1446,10 @@ struct eventdev_ops { /**< Reset eth Tx adapter statistics */ eventdev_eth_tx_adapter_instance_get_t eth_tx_adapter_instance_get; /**< Get Tx adapter instance id for Tx queue */ + eventdev_eth_tx_adapter_queue_start eth_tx_adapter_queue_start; + /**< Start Tx queue assigned to Tx adapter instance */ + eventdev_eth_tx_adapter_queue_stop eth_tx_adapter_queue_stop; + /**< Stop Tx queue assigned to Tx adapter instance */ eventdev_selftest dev_selftest; /**< Start eventdev Selftest */ diff --git a/lib/eventdev/rte_event_eth_tx_adapter.c b/lib/eventdev/rte_event_eth_tx_adapter.c index 7e82fe030c..60baf421be 100644 --- a/lib/eventdev/rte_event_eth_tx_adapter.c +++ b/lib/eventdev/rte_event_eth_tx_adapter.c @@ -47,6 +47,12 @@ #define txa_dev_instance_get(id) \ txa_evdev(id)->dev_ops->eth_tx_adapter_instance_get +#define txa_dev_queue_start(id) \ + txa_evdev(id)->dev_ops->eth_tx_adapter_queue_start + +#define txa_dev_queue_stop(id) \ + txa_evdev(id)->dev_ops->eth_tx_adapter_queue_stop + #define RTE_EVENT_ETH_TX_ADAPTER_ID_VALID_OR_ERR_RET(id, retval) \ do { \ if (!txa_valid_id(id)) { \ @@ -94,6 +100,8 @@ struct txa_retry { struct txa_service_queue_info { /* Queue has been added */ uint8_t added; + /* Queue is stopped */ + bool stopped; /* Retry callback argument */ struct txa_retry txa_retry; /* Tx buffer */ @@ -556,7 +564,7 @@ txa_process_event_vector(struct txa_service_data *txa, port = vec->port; queue = vec->queue; tqi = txa_service_queue(txa, port, queue); - if (unlikely(tqi == NULL || !tqi->added)) { + if (unlikely(tqi == NULL || !tqi->added || tqi->stopped)) { rte_pktmbuf_free_bulk(mbufs, vec->nb_elem); rte_mempool_put(rte_mempool_from_obj(vec), vec); return 0; @@ -570,7 +578,8 @@ txa_process_event_vector(struct txa_service_data *txa, port = mbufs[i]->port; queue = rte_event_eth_tx_adapter_txq_get(mbufs[i]); tqi = txa_service_queue(txa, port, queue); - if (unlikely(tqi == NULL || !tqi->added)) { + if (unlikely(tqi == NULL || !tqi->added || + tqi->stopped)) { rte_pktmbuf_free(mbufs[i]); continue; } @@ -607,7 +616,8 @@ txa_service_tx(struct txa_service_data *txa, struct rte_event *ev, queue = rte_event_eth_tx_adapter_txq_get(m); tqi = txa_service_queue(txa, port, queue); - if (unlikely(tqi == NULL || !tqi->added)) { + if (unlikely(tqi == NULL || !tqi->added || + tqi->stopped)) { rte_pktmbuf_free(m); continue; } @@ -671,7 +681,8 @@ txa_service_func(void *args) for (q = 0; q < dev->data->nb_tx_queues; q++) { tqi = txa_service_queue(txa, i, q); - if (unlikely(tqi == NULL || !tqi->added)) + if (unlikely(tqi == NULL || !tqi->added || + tqi->stopped)) continue; nb_tx += rte_eth_tx_buffer_flush(i, q, @@ -866,6 +877,7 @@ txa_service_queue_add(uint8_t id, tqi->tx_buf = tb; tqi->added = 1; + tqi->stopped = false; tdi->nb_queues++; txa->nb_queues++; @@ -884,6 +896,20 @@ txa_service_queue_add(uint8_t id, return -1; } +static inline void +txa_txq_buffer_drain(struct txa_service_queue_info *tqi) +{ + struct rte_eth_dev_tx_buffer *b; + uint16_t i; + + b = tqi->tx_buf; + + for (i = 0; i < b->length; i++) + rte_pktmbuf_free(b->pkts[i]); + + b->length = 0; +} + static int txa_service_queue_del(uint8_t id, const struct rte_eth_dev *dev, @@ -929,6 +955,8 @@ txa_service_queue_del(uint8_t id, if (tqi == NULL || !tqi->added) goto ret_unlock; + /* Drain the buffered mbufs */ + txa_txq_buffer_drain(tqi); tb = tqi->tx_buf; tqi->added = 0; tqi->tx_buf = NULL; @@ -1319,3 +1347,80 @@ rte_event_eth_tx_adapter_instance_get(uint16_t eth_dev_id, return -EINVAL; } + +static int +txa_queue_start_state_set(uint16_t eth_dev_id, uint16_t tx_queue_id, + bool start_state) +{ + struct txa_service_data *txa; + struct txa_service_queue_info *tqi = NULL; + uint8_t txa_inst_id; + int ret; + uint32_t caps = 0; + + /* Below API already does validation of input parameters. + * Hence skipping the validation here. + */ + ret = rte_event_eth_tx_adapter_instance_get(eth_dev_id, + tx_queue_id, + &txa_inst_id); + if (ret < 0) + return -EINVAL; + + TXA_CHECK_OR_ERR_RET(txa_inst_id); + + txa = txa_service_id_to_data(txa_inst_id); + ret = rte_event_eth_tx_adapter_caps_get(txa->eventdev_id, + eth_dev_id, + &caps); + if (ret < 0) + return -EINVAL; + + if (start_state == true) { + if (caps & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT) { + ret = txa_dev_queue_start(txa_inst_id) ? + txa_dev_queue_start(txa_inst_id)(txa_inst_id, + eth_dev_id, + tx_queue_id) : 0; + return ret; + } + rte_spinlock_lock(&txa->tx_lock); + tqi = txa_service_queue(txa, eth_dev_id, tx_queue_id); + if (unlikely(tqi == NULL || !tqi->added)) { + rte_spinlock_unlock(&txa->tx_lock); + return -EINVAL; + } + tqi->stopped = !start_state; + rte_spinlock_unlock(&txa->tx_lock); + } else { + if (caps & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT) { + ret = txa_dev_queue_stop(txa_inst_id) ? + txa_dev_queue_stop(txa_inst_id)(txa_inst_id, + eth_dev_id, + tx_queue_id) : 0; + return ret; + } + rte_spinlock_lock(&txa->tx_lock); + tqi = txa_service_queue(txa, eth_dev_id, tx_queue_id); + if (unlikely(tqi == NULL || !tqi->added)) { + rte_spinlock_unlock(&txa->tx_lock); + return -EINVAL; + } + txa_txq_buffer_drain(tqi); + tqi->stopped = !start_state; + rte_spinlock_unlock(&txa->tx_lock); + } + return 0; +} + +int +rte_event_eth_tx_adapter_queue_start(uint16_t eth_dev_id, uint16_t tx_queue_id) +{ + return txa_queue_start_state_set(eth_dev_id, tx_queue_id, true); +} + +int +rte_event_eth_tx_adapter_queue_stop(uint16_t eth_dev_id, uint16_t tx_queue_id) +{ + return txa_queue_start_state_set(eth_dev_id, tx_queue_id, false); +} diff --git a/lib/eventdev/rte_event_eth_tx_adapter.h b/lib/eventdev/rte_event_eth_tx_adapter.h index 9432b740e8..2c387784da 100644 --- a/lib/eventdev/rte_event_eth_tx_adapter.h +++ b/lib/eventdev/rte_event_eth_tx_adapter.h @@ -35,6 +35,8 @@ * - rte_event_eth_tx_adapter_event_port_get() * - rte_event_eth_tx_adapter_service_id_get() * - rte_event_eth_tx_adapter_instance_get() + * - rte_event_eth_tx_adapter_queue_start() + * - rte_event_eth_tx_adapter_queue_stop() * * The application creates the adapter using * rte_event_eth_tx_adapter_create() or rte_event_eth_tx_adapter_create_ext(). @@ -446,6 +448,46 @@ int rte_event_eth_tx_adapter_instance_get(uint16_t eth_dev_id, uint16_t tx_queue_id, uint8_t *txa_inst_id); +/** + * Enables the Tx adapter to start enqueueing packets to the + * Tx queue. + * + * This function is provided so that the application can + * resume enqueueing packets that reference packets for + * after calling + * rte_event_eth_tx_adapter_queue_stop() + * @see rte_event_eth_tx_adapter_queue_stop + * + * @param eth_dev_id + * Port identifier of Ethernet device. + * @param tx_queue_id + * Ethernet device transmit queue index. + * @return + * - 0: Success + * - <0: Error code on failure + */ +__rte_experimental +int +rte_event_eth_tx_adapter_queue_start(uint16_t eth_dev_id, uint16_t tx_queue_id); + +/** + * Stops the Tx adapter runtime function from enqueueing any packets + * to the associated Tx queue. This API also frees any packets that may + * have been buffered for this queue. All inflight packets destined to the + * queue are freed by the adapter runtime until the queue is started again. + * @see rte_event_eth_tx_adapter_queue_start + * + * @param eth_dev_id + * Port identifier of Ethernet device. + * @param tx_queue_id + * Ethernet device transmit queue index. + * @return + * - 0: Success + * - <0: Error code on failure + */ +__rte_experimental +int +rte_event_eth_tx_adapter_queue_stop(uint16_t eth_dev_id, uint16_t tx_queue_id); #ifdef __cplusplus } diff --git a/lib/eventdev/version.map b/lib/eventdev/version.map index 9a71cf3f8f..dd63ec6f68 100644 --- a/lib/eventdev/version.map +++ b/lib/eventdev/version.map @@ -116,6 +116,8 @@ EXPERIMENTAL { # added in 22.11 rte_event_eth_rx_adapter_instance_get; rte_event_eth_tx_adapter_instance_get; + rte_event_eth_tx_adapter_queue_start; + rte_event_eth_tx_adapter_queue_stop; }; INTERNAL { -- 2.25.1