From: Bruce Richardson <bruce.richardson@intel.com>
To: dev@dpdk.org
Subject: [dpdk-dev] [PATCH] distributor: split get_pkt into request and poll
Date: Thu, 19 Jun 2014 22:12:35 +0100 [thread overview]
Message-ID: <1403212355-989-1-git-send-email-bruce.richardson@intel.com> (raw)
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 <bruce.richardson@intel.com>
---
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
next reply other threads:[~2014-06-19 21:12 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-19 21:12 Bruce Richardson [this message]
2014-06-20 9:57 ` De Lara Guarch, Pablo
2014-06-20 16:03 ` Thomas Monjalon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1403212355-989-1-git-send-email-bruce.richardson@intel.com \
--to=bruce.richardson@intel.com \
--cc=dev@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).