[dpdk-dev,19/39] event/octeontx: add support worker dequeue function

Message ID 1488562101-6658-20-git-send-email-jerin.jacob@caviumnetworks.com (mailing list archive)
State Superseded, archived
Delegated to: Jerin Jacob
Headers

Checks

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

Commit Message

Jerin Jacob March 3, 2017, 5:28 p.m. UTC
  If device is configured with RTE_EVENT_DEV_CFG_PER_DEQUEUE_TIMEOUT
configuration then use different fast path dequeue handler to wait till
requested amount of nanosecond if the event is not available.

Signed-off-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
Signed-off-by: Santosh Shukla <santosh.shukla@caviumnetworks.com>
---
 drivers/event/octeontx/ssovf_evdev.h  |  7 +++++
 drivers/event/octeontx/ssovf_worker.c | 52 +++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+)
  

Comments

Eads, Gage March 20, 2017, 9:11 p.m. UTC | #1
Hi Jerin,

>  -----Original Message-----
>  From: Jerin Jacob [mailto:jerin.jacob@caviumnetworks.com]
>  Sent: Friday, March 3, 2017 11:28 AM
>  To: dev@dpdk.org
>  Cc: thomas.monjalon@6wind.com; Richardson, Bruce
>  <bruce.richardson@intel.com>; Van Haaren, Harry
>  <harry.van.haaren@intel.com>; hemant.agrawal@nxp.com; Eads, Gage
>  <gage.eads@intel.com>; nipun.gupta@nxp.com;
>  santosh.shukla@caviumnetworks.com; Jerin Jacob
>  <jerin.jacob@caviumnetworks.com>
>  Subject: [dpdk-dev] [PATCH 19/39] event/octeontx: add support worker
>  dequeue function
>  
>  If device is configured with RTE_EVENT_DEV_CFG_PER_DEQUEUE_TIMEOUT
>  configuration then use different fast path dequeue handler to wait till
>  requested amount of nanosecond if the event is not available.
>  
>  Signed-off-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
>  Signed-off-by: Santosh Shukla <santosh.shukla@caviumnetworks.com>
>  ---
>   drivers/event/octeontx/ssovf_evdev.h  |  7 +++++
>  drivers/event/octeontx/ssovf_worker.c | 52
>  +++++++++++++++++++++++++++++++++++
>   2 files changed, 59 insertions(+)
>  
>  diff --git a/drivers/event/octeontx/ssovf_evdev.h
>  b/drivers/event/octeontx/ssovf_evdev.h
>  index fac42f5..2cd9147 100644
>  --- a/drivers/event/octeontx/ssovf_evdev.h
>  +++ b/drivers/event/octeontx/ssovf_evdev.h
>  @@ -190,5 +190,12 @@ ssovf_pmd_priv(const struct rte_eventdev *eventdev)
>  uint16_t ssows_enq(void *port, const struct rte_event *ev);  uint16_t
>  ssows_enq_burst(void *port,
>   		const struct rte_event ev[], uint16_t nb_events);
>  +uint16_t ssows_deq(void *port, struct rte_event *ev, uint64_t
>  +timeout_ticks); uint16_t ssows_deq_burst(void *port, struct rte_event ev[],
>  +		uint16_t nb_events, uint64_t timeout_ticks); uint16_t
>  +ssows_deq_timeout(void *port, struct rte_event *ev,
>  +		uint64_t timeout_ticks);
>  +uint16_t ssows_deq_timeout_burst(void *port, struct rte_event ev[],
>  +		uint16_t nb_events, uint64_t timeout_ticks);
>  
>   #endif /* __SSOVF_EVDEV_H__ */
>  diff --git a/drivers/event/octeontx/ssovf_worker.c
>  b/drivers/event/octeontx/ssovf_worker.c
>  index 7ec78b4..e0d17b9 100644
>  --- a/drivers/event/octeontx/ssovf_worker.c
>  +++ b/drivers/event/octeontx/ssovf_worker.c
>  @@ -226,6 +226,58 @@ ssows_release_event(struct ssows *ws)  }
>  
>   force_inline uint16_t __hot
>  +ssows_deq(void *port, struct rte_event *ev, uint64_t timeout_ticks) {
>  +	struct ssows *ws = port;
>  +
>  +	RTE_SET_USED(timeout_ticks);
>  +
>  +	ssows_swtag_wait(ws);
>  +	if (ws->swtag_req) {
>  +		ws->swtag_req = 0;
>  +		return 1;
>  +	} else {
>  +		return ssows_get_work(ws, ev);
>  +	}
>  +}

Should ssows_deq() fill in the ev structure when swtag_req is 1? I see that the flag is set when an event is forwarded to the same queue/group it was received on -- is the expectation that ev will point to that forwarded event, such that the user receives it when they next dequeue an event?

Thanks,
Gage
  
Jerin Jacob March 21, 2017, 3:21 a.m. UTC | #2
On Mon, Mar 20, 2017 at 09:11:35PM +0000, Eads, Gage wrote:
> Hi Jerin,

Hi Gage,

> 
> >  -----Original Message-----
> >  From: Jerin Jacob [mailto:jerin.jacob@caviumnetworks.com]
> >  Sent: Friday, March 3, 2017 11:28 AM
> >  To: dev@dpdk.org
> >  Cc: thomas.monjalon@6wind.com; Richardson, Bruce
> >  <bruce.richardson@intel.com>; Van Haaren, Harry
> >  <harry.van.haaren@intel.com>; hemant.agrawal@nxp.com; Eads, Gage
> >  <gage.eads@intel.com>; nipun.gupta@nxp.com;
> >  santosh.shukla@caviumnetworks.com; Jerin Jacob
> >  <jerin.jacob@caviumnetworks.com>
> >  Subject: [dpdk-dev] [PATCH 19/39] event/octeontx: add support worker
> >  dequeue function
> >  
> >  If device is configured with RTE_EVENT_DEV_CFG_PER_DEQUEUE_TIMEOUT
> >  configuration then use different fast path dequeue handler to wait till
> >  requested amount of nanosecond if the event is not available.
> >  
> >  Signed-off-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> >  Signed-off-by: Santosh Shukla <santosh.shukla@caviumnetworks.com>
> >  ---
> >   drivers/event/octeontx/ssovf_evdev.h  |  7 +++++
> >  drivers/event/octeontx/ssovf_worker.c | 52
> >  +++++++++++++++++++++++++++++++++++
> >   2 files changed, 59 insertions(+)
> >  
> >  diff --git a/drivers/event/octeontx/ssovf_evdev.h
> >  b/drivers/event/octeontx/ssovf_evdev.h
> >  index fac42f5..2cd9147 100644
> >  --- a/drivers/event/octeontx/ssovf_evdev.h
> >  +++ b/drivers/event/octeontx/ssovf_evdev.h
> >  @@ -190,5 +190,12 @@ ssovf_pmd_priv(const struct rte_eventdev *eventdev)
> >  uint16_t ssows_enq(void *port, const struct rte_event *ev);  uint16_t
> >  ssows_enq_burst(void *port,
> >   		const struct rte_event ev[], uint16_t nb_events);
> >  +uint16_t ssows_deq(void *port, struct rte_event *ev, uint64_t
> >  +timeout_ticks); uint16_t ssows_deq_burst(void *port, struct rte_event ev[],
> >  +		uint16_t nb_events, uint64_t timeout_ticks); uint16_t
> >  +ssows_deq_timeout(void *port, struct rte_event *ev,
> >  +		uint64_t timeout_ticks);
> >  +uint16_t ssows_deq_timeout_burst(void *port, struct rte_event ev[],
> >  +		uint16_t nb_events, uint64_t timeout_ticks);
> >  
> >   #endif /* __SSOVF_EVDEV_H__ */
> >  diff --git a/drivers/event/octeontx/ssovf_worker.c
> >  b/drivers/event/octeontx/ssovf_worker.c
> >  index 7ec78b4..e0d17b9 100644
> >  --- a/drivers/event/octeontx/ssovf_worker.c
> >  +++ b/drivers/event/octeontx/ssovf_worker.c
> >  @@ -226,6 +226,58 @@ ssows_release_event(struct ssows *ws)  }
> >  
> >   force_inline uint16_t __hot
> >  +ssows_deq(void *port, struct rte_event *ev, uint64_t timeout_ticks) {
> >  +	struct ssows *ws = port;
> >  +
> >  +	RTE_SET_USED(timeout_ticks);
> >  +
> >  +	ssows_swtag_wait(ws);
> >  +	if (ws->swtag_req) {
> >  +		ws->swtag_req = 0;
> >  +		return 1;
> >  +	} else {
> >  +		return ssows_get_work(ws, ev);
> >  +	}
> >  +}
> 
> Should ssows_deq() fill in the ev structure when swtag_req is 1? I see that the flag is set when an event is forwarded to the same queue/group it was received on -- is the expectation that ev will point to that forwarded event, such that the user receives it when they next dequeue an event?

Yes. The user receives the same event.HW supports event pinning to lower the
latency.


> 
> Thanks,
> Gage
>
  
Eads, Gage March 23, 2017, 6:51 p.m. UTC | #3
Hi Jerin,

<snip>

>  +force_inline uint16_t __hot
>  +ssows_deq_timeout(void *port, struct rte_event *ev, uint64_t
>  +timeout_ticks) {
>  +	struct ssows *ws = port;
>  +	uint64_t iter;
>  +	uint16_t ret = 1;
>  +
>  +	ssows_swtag_wait(ws);
>  +	if (ws->swtag_req) {
>  +		ws->swtag_req = 0;
>  +	} else {
>  +		ret = ssows_get_work(ws, ev);
>  +		for (iter = 1; iter < timeout_ticks && (ret == 0); iter++)
>  +			ret = ssows_get_work(ws, ev);
>  +	}
>  +	return ret;
>  +}

If I understand this correctly, each ssows_get_work() call will wait up to N ns, where N is the dequeue_timeout_ns value supplied to ssovf_mbox_getwork_tmo_set() in ssovf_configure().

So in ssows_deq_timeout, the wait time is (worst case) timeout_ticks * (N * (ns to tick conversion factor)) ticks, which depends on the user-supplied N at eventdev configuration time.

Perhaps in ssovf_configure, if the RTE_EVENT_DEV_CFG_PER_DEQUEUE_TIMEOUT flag is used, the getwork timeout should be set to 1 tick?

Thanks,
Gage
  
Jerin Jacob March 24, 2017, 11:16 a.m. UTC | #4
On Thu, Mar 23, 2017 at 06:51:07PM +0000, Eads, Gage wrote:
> Hi Jerin,

Hi Gage,

> 
> <snip>
> 
> >  +force_inline uint16_t __hot
> >  +ssows_deq_timeout(void *port, struct rte_event *ev, uint64_t
> >  +timeout_ticks) {
> >  +	struct ssows *ws = port;
> >  +	uint64_t iter;
> >  +	uint16_t ret = 1;
> >  +
> >  +	ssows_swtag_wait(ws);
> >  +	if (ws->swtag_req) {
> >  +		ws->swtag_req = 0;
> >  +	} else {
> >  +		ret = ssows_get_work(ws, ev);
> >  +		for (iter = 1; iter < timeout_ticks && (ret == 0); iter++)
> >  +			ret = ssows_get_work(ws, ev);
> >  +	}
> >  +	return ret;
> >  +}
> 
> If I understand this correctly, each ssows_get_work() call will wait up to N ns, where N is the dequeue_timeout_ns value supplied to ssovf_mbox_getwork_tmo_set() in ssovf_configure().
> 
> So in ssows_deq_timeout, the wait time is (worst case) timeout_ticks * (N * (ns to tick conversion factor)) ticks, which depends on the user-supplied N at eventdev configuration time.
> 
> Perhaps in ssovf_configure, if the RTE_EVENT_DEV_CFG_PER_DEQUEUE_TIMEOUT flag is used, the getwork timeout should be set to 1 tick?

I agree. That will improve the timeout accuracy.I will change to
ssovf_mbox_getwork_tmo_set(conf->min_dequeue_timeout_ns) in
ssovf_configure if RTE_EVENT_DEV_CFG_PER_DEQUEUE_TIMEOUT flag is set.

Thanks

> Thanks,
> Gage
  

Patch

diff --git a/drivers/event/octeontx/ssovf_evdev.h b/drivers/event/octeontx/ssovf_evdev.h
index fac42f5..2cd9147 100644
--- a/drivers/event/octeontx/ssovf_evdev.h
+++ b/drivers/event/octeontx/ssovf_evdev.h
@@ -190,5 +190,12 @@  ssovf_pmd_priv(const struct rte_eventdev *eventdev)
 uint16_t ssows_enq(void *port, const struct rte_event *ev);
 uint16_t ssows_enq_burst(void *port,
 		const struct rte_event ev[], uint16_t nb_events);
+uint16_t ssows_deq(void *port, struct rte_event *ev, uint64_t timeout_ticks);
+uint16_t ssows_deq_burst(void *port, struct rte_event ev[],
+		uint16_t nb_events, uint64_t timeout_ticks);
+uint16_t ssows_deq_timeout(void *port, struct rte_event *ev,
+		uint64_t timeout_ticks);
+uint16_t ssows_deq_timeout_burst(void *port, struct rte_event ev[],
+		uint16_t nb_events, uint64_t timeout_ticks);
 
 #endif /* __SSOVF_EVDEV_H__ */
diff --git a/drivers/event/octeontx/ssovf_worker.c b/drivers/event/octeontx/ssovf_worker.c
index 7ec78b4..e0d17b9 100644
--- a/drivers/event/octeontx/ssovf_worker.c
+++ b/drivers/event/octeontx/ssovf_worker.c
@@ -226,6 +226,58 @@  ssows_release_event(struct ssows *ws)
 }
 
 force_inline uint16_t __hot
+ssows_deq(void *port, struct rte_event *ev, uint64_t timeout_ticks)
+{
+	struct ssows *ws = port;
+
+	RTE_SET_USED(timeout_ticks);
+
+	ssows_swtag_wait(ws);
+	if (ws->swtag_req) {
+		ws->swtag_req = 0;
+		return 1;
+	} else {
+		return ssows_get_work(ws, ev);
+	}
+}
+
+force_inline uint16_t __hot
+ssows_deq_timeout(void *port, struct rte_event *ev, uint64_t timeout_ticks)
+{
+	struct ssows *ws = port;
+	uint64_t iter;
+	uint16_t ret = 1;
+
+	ssows_swtag_wait(ws);
+	if (ws->swtag_req) {
+		ws->swtag_req = 0;
+	} else {
+		ret = ssows_get_work(ws, ev);
+		for (iter = 1; iter < timeout_ticks && (ret == 0); iter++)
+			ret = ssows_get_work(ws, ev);
+	}
+	return ret;
+}
+
+uint16_t __hot
+ssows_deq_burst(void *port, struct rte_event ev[], uint16_t nb_events,
+		uint64_t timeout_ticks)
+{
+	RTE_SET_USED(nb_events);
+
+	return ssows_deq(port, ev, timeout_ticks);
+}
+
+uint16_t __hot
+ssows_deq_timeout_burst(void *port, struct rte_event ev[], uint16_t nb_events,
+			uint64_t timeout_ticks)
+{
+	RTE_SET_USED(nb_events);
+
+	return ssows_deq_timeout(port, ev, timeout_ticks);
+}
+
+force_inline uint16_t __hot
 ssows_enq(void *port, const struct rte_event *ev)
 {
 	struct ssows *ws = port;