From patchwork Thu Mar 23 11:37:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Sexton, Rory" X-Patchwork-Id: 125454 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 2C8B342825; Thu, 23 Mar 2023 12:37:59 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id F12DF42B71; Thu, 23 Mar 2023 12:37:53 +0100 (CET) Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by mails.dpdk.org (Postfix) with ESMTP id CA6F34021D for ; Thu, 23 Mar 2023 12:37:51 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1679571472; x=1711107472; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=D2RHPnlYbLnWcnCEgONInHbzpxQC6oxJqR7DKEgxygs=; b=D6OzISbDTg4JcqrMhrlS/wdprjDS/VLRD2vZpdJkElJbd05KCfB0mYFp STvIbAxl+lmCB6G/32Tv2DivKLcfI2GWvs99mC6UzIqyxHOi89TZJ1NeE TSMuAy2avF8Bu2PskegfFDvqmlMW+oPJzDseXtgd4KAPCafIKFTN8l4xA rRyUiZRfVrMQkjyCmpTnQEOxLiITqJEOV+BDOw6PNq31QtiMLfCk/kZsn 5koFwW7Rl7E7qY1D6RS9FbieDBKqjBcB7m5JTj366xMgMDLYrPVlfvGsV n8k/kGNSx9iCQiAgbce4ka5ZvkZ+M05+klRGdsDU8hqt7o3tYJ9kCCo4G w==; X-IronPort-AV: E=McAfee;i="6600,9927,10657"; a="323310600" X-IronPort-AV: E=Sophos;i="5.98,283,1673942400"; d="scan'208";a="323310600" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Mar 2023 04:37:51 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10657"; a="806220490" X-IronPort-AV: E=Sophos;i="5.98,283,1673942400"; d="scan'208";a="806220490" Received: from silpixa00401024.ir.intel.com (HELO silpixa00401024.default.svc.cluster.local) ([10.237.223.91]) by orsmga004.jf.intel.com with ESMTP; 23 Mar 2023 04:37:50 -0700 From: Rory Sexton To: honnappa.nagarahalli@arm.com, konstantin.v.ananyev@yandex.ru Cc: dev@dpdk.org, Rory Sexton Subject: [RFC 1/1] ring: add infrastructure to allow callbacks within the ring library Date: Thu, 23 Mar 2023 11:37:43 +0000 Message-Id: <20230323113743.4086730-2-rory.sexton@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230323113743.4086730-1-rory.sexton@intel.com> References: <20230323113743.4086730-1-rory.sexton@intel.com> MIME-Version: 1.0 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 Adding initial code to give a feel for what it would look like if callbacks were supported by the ring dequeue functions within the ring library. They could be optionally compiled in/out as required. Signed-off-by: Rory Sexton --- lib/ring/rte_ring.h | 133 ++++++++++++++++++++++++++++++++++++++- lib/ring/rte_ring_core.h | 3 + 2 files changed, 135 insertions(+), 1 deletion(-) diff --git a/lib/ring/rte_ring.h b/lib/ring/rte_ring.h index 7e4cd60650..9cda49ee51 100644 --- a/lib/ring/rte_ring.h +++ b/lib/ring/rte_ring.h @@ -789,6 +789,126 @@ rte_ring_sc_dequeue_burst(struct rte_ring *r, void **obj_table, n, available); } +#ifdef RTE_RING_DEQUEUE_CALLBACKS +/** + * Function type used for ring dequeue callbacks. + * + * The callback function is called on dequeue with a burst of objects that have + * been dequeued on the given ring. + * + * @param r + * A pointer to the ring structure. + * @param obj_table + * A pointer to a table of void * pointers (objects) filled by the dequeue. + * @param n + * The number of objects to dequeued from the ring to the obj_table. + * @param available + * If non-NULL, returns the number of remaining ring entries after the + * dequeue has finished. + * @param user_param + * The arbitrary user parameter passed in by the application when the callback + * was originally configured. + * @return + * The number of packets returned to the user. + */ +typedef uint16_t (*rte_ring_dequeue_callback_fn)(struct rte_ring *r, + void **obj_table, unsigned int n, unsigned int *available, + void *user_param); + +/** + * @internal + * Structure used to hold information about the callbacks to be called for a + * ring on dequeue. + */ +struct rte_ring_dequeue_callback { + struct rte_ring_dequeue_callback *next; + rte_ring_dequeue_callback_fn fn; + void *param; +}; + +/** + * Add a callback to be called on dequeue of a given ring. + * + * This API configures a function to be called for each burst of + * objects dequeued from a given RING. The return value is a pointer + * that can be used to later remove the callback using + * rte_ring_remove_dequeue_callback(). + * + * Multiple functions are called in the order that they are added. + * + * @param r + * A pointer to the ring structure. + * @param fn + * The callback function. + * @param user_param + * A generic pointer parameter which will be passed to each invocation of the + * callback function on this ring. + * + * @return + * NULL on error. + * On success, a pointer value which can later be used to remove the callback. + */ +const struct rte_ring_dequeue_callback * +rte_ring_add_dequeue_callback(struct rte_ring *r, + rte_ring_dequeue_callback_fn fn, void *user_param); + +/** + * Remove a callback from a given ring. + * + * This function is used to removed callbacks that were added to a ring + * dequeue using rte_ring_add_dequeue_callback(). + * + * Note: the callback is removed from the callback list but it isn't freed + * since the it may still be in use. The memory for the callback can be + * subsequently freed back by the application by calling rte_free(): + * + * - Immediately - if the user knows that no callbacks are in flight + * e.g. if called from the thread doing the dequeue on that ring. + * + * - After a short delay - where the delay is sufficient to allow any + * in-flight callbacks to complete. Alternately, the RCU mechanism can be + * used to detect when data plane threads have ceased referencing the + * callback memory. + * + * @param r + * A pointer to the ring structure. + * @param user_cb + * User supplied callback created via rte_ring_add_dequeue_callback(). + * + * @return + * - 0: Success. Callback was removed. + * - -ENODEV: If *ring* is invalid. + * - -ENOTSUP: Callback support is not available. + * - -EINVAL: The callback is NULL or not found for the ring. + */ +int rte_ring_remove_dequeue_callback(struct rte_ring *r, + const struct rte_ring_dequeue_callback *user_cb); + +/** + * @internal + * Helper routine for rte_ring_dequeue_burst(). + * Invokes dequeue callbacks if any, etc. + * + * @param r + * A pointer to the ring structure. + * @param obj_table + * A pointer to a table of void * pointers (objects) filled by the dequeue. + * @param n + * The number of objects to dequeued from the ring to the obj_table. + * @param available + * If non-NULL, returns the number of remaining ring entries after the + * dequeue has finished. + * @param opaque + * Opaque pointer of ring dequeue callback related data. + * + * @return + * The number of objects effectively supplied to the @p obj_table array. + */ +uint16_t rte_ring_call_dequeue_callbacks(struct rte_ring *r, + void **obj_table, unsigned int n, unsigned int *available, + void *opaque); +#endif + /** * Dequeue multiple objects from a ring up to a maximum number. * @@ -812,8 +932,19 @@ static __rte_always_inline unsigned int rte_ring_dequeue_burst(struct rte_ring *r, void **obj_table, unsigned int n, unsigned int *available) { - return rte_ring_dequeue_burst_elem(r, obj_table, sizeof(void *), + unsigned int nb_rx; + nb_rx = rte_ring_dequeue_burst_elem(r, obj_table, sizeof(void *), n, available); + +#ifdef RTE_RING_DEQUEUE_CALLBACKS + { + if (unlikely(r->cb != NULL)) + nb_rx = rte_ring_call_dequeue_callbacks(r, obj_table, + nb_rx, available, r->cb); + } +#endif + + return nb_rx; } #ifdef __cplusplus diff --git a/lib/ring/rte_ring_core.h b/lib/ring/rte_ring_core.h index 82b237091b..603e1b45f0 100644 --- a/lib/ring/rte_ring_core.h +++ b/lib/ring/rte_ring_core.h @@ -147,6 +147,9 @@ struct rte_ring { struct rte_ring_rts_headtail rts_cons; } __rte_cache_aligned; + /** points to array of ring callback data pointers */ + void **cb; + char pad2 __rte_cache_aligned; /**< empty cache line */ };