From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id E0913AFDD for ; Thu, 19 Jun 2014 23:12:22 +0200 (CEST) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP; 19 Jun 2014 14:07:17 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.01,509,1400050800"; d="scan'208";a="531221948" Received: from irvmail001.ir.intel.com ([163.33.26.43]) by orsmga001.jf.intel.com with ESMTP; 19 Jun 2014 14:12:37 -0700 Received: from sivswdev02.ir.intel.com (sivswdev02.ir.intel.com [10.237.217.46]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id s5JLCb0V006780; Thu, 19 Jun 2014 22:12:37 +0100 Received: from sivswdev02.ir.intel.com (localhost [127.0.0.1]) by sivswdev02.ir.intel.com with ESMTP id s5JLCaWl001288; Thu, 19 Jun 2014 22:12:36 +0100 Received: (from bricha3@localhost) by sivswdev02.ir.intel.com with id s5JLCanv001284; Thu, 19 Jun 2014 22:12:36 +0100 From: Bruce Richardson To: dev@dpdk.org Date: Thu, 19 Jun 2014 22:12:35 +0100 Message-Id: <1403212355-989-1-git-send-email-bruce.richardson@intel.com> X-Mailer: git-send-email 1.7.0.7 Subject: [dpdk-dev] [PATCH] distributor: split get_pkt into request and poll X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 19 Jun 2014 21:12:23 -0000 Take the existing get_pkt API and split out the parts for requesting a new packet from the part to poll for arrival of a new packet. These individual functions can then be used independently of the get function, which still acts as before. The split functions for request and poll will allow a worker to pull packets from multiple distributors, or to act as multiple workers with a single distributor if needed for better performance. Signed-off-by: Bruce Richardson --- lib/librte_distributor/rte_distributor.c | 27 ++++++++++++++++--- lib/librte_distributor/rte_distributor.h | 45 ++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 4 deletions(-) diff --git a/lib/librte_distributor/rte_distributor.c b/lib/librte_distributor/rte_distributor.c index 5eee442..ec6094f 100644 --- a/lib/librte_distributor/rte_distributor.c +++ b/lib/librte_distributor/rte_distributor.c @@ -103,8 +103,8 @@ TAILQ_HEAD(rte_distributor_list, rte_distributor); /**** APIs called by workers ****/ -struct rte_mbuf * -rte_distributor_get_pkt(struct rte_distributor *d, +void +rte_distributor_request_pkt(struct rte_distributor *d, unsigned worker_id, struct rte_mbuf *oldpkt) { union rte_distributor_buffer *buf = &d->bufs[worker_id]; @@ -113,13 +113,32 @@ rte_distributor_get_pkt(struct rte_distributor *d, while (unlikely(buf->bufptr64 & RTE_DISTRIB_FLAGS_MASK)) rte_pause(); buf->bufptr64 = req; - while (buf->bufptr64 & RTE_DISTRIB_GET_BUF) - rte_pause(); +} + +struct rte_mbuf * +rte_distributor_poll_pkt(struct rte_distributor *d, + unsigned worker_id) +{ + union rte_distributor_buffer *buf = &d->bufs[worker_id]; + if (buf->bufptr64 & RTE_DISTRIB_GET_BUF) + return NULL; + /* since bufptr64 is signed, this should be an arithmetic shift */ int64_t ret = buf->bufptr64 >> RTE_DISTRIB_FLAG_BITS; return (struct rte_mbuf *)((uintptr_t)ret); } +struct rte_mbuf * +rte_distributor_get_pkt(struct rte_distributor *d, + unsigned worker_id, struct rte_mbuf *oldpkt) +{ + struct rte_mbuf *ret; + rte_distributor_request_pkt(d, worker_id, oldpkt); + while ((ret = rte_distributor_poll_pkt(d, worker_id)) == NULL) + rte_pause(); + return ret; +} + int rte_distributor_return_pkt(struct rte_distributor *d, unsigned worker_id, struct rte_mbuf *oldpkt) diff --git a/lib/librte_distributor/rte_distributor.h b/lib/librte_distributor/rte_distributor.h index 1e41dce..8e391ed 100644 --- a/lib/librte_distributor/rte_distributor.h +++ b/lib/librte_distributor/rte_distributor.h @@ -193,6 +193,51 @@ int rte_distributor_return_pkt(struct rte_distributor *d, unsigned worker_id, struct rte_mbuf *mbuf); +/** + * API called by a worker to request a new packet to process. + * Any previous packet given to the worker is assumed to have completed + * processing, and may be optionally returned to the distributor via + * the oldpkt parameter. + * Unlike rte_distributor_get_pkt(), this function does not wait for a new + * packet to be provided by the distributor. + * + * NOTE: after calling this function, rte_distributor_poll_pkt() should + * be used to poll for the packet requested. The rte_distributor_get_pkt() + * API should *not* be used to try and retrieve the new packet. + * + * @param d + * The distributor instance to be used + * @param worker_id + * The worker instance number to use - must be less that num_workers passed + * at distributor creation time. + * @param oldpkt + * The previous packet, if any, being processed by the worker + */ +void +rte_distributor_request_pkt(struct rte_distributor *d, + unsigned worker_id, struct rte_mbuf *oldpkt); + +/** + * API called by a worker to check for a new packet that was previously + * requested by a call to rte_distributor_request_pkt(). It does not wait + * for the new packet to be available, but returns NULL if the request has + * not yet been fulfilled by the distributor. + * + * @param d + * The distributor instance to be used + * @param worker_id + * The worker instance number to use - must be less that num_workers passed + * at distributor creation time. + * + * @return + * A new packet to be processed by the worker thread, or NULL if no + * packet is yet available. + */ +struct rte_mbuf * +rte_distributor_poll_pkt(struct rte_distributor *d, + unsigned worker_id); + + /******************************************/ #ifdef __cplusplus -- 1.9.3