Implement RTE_EVENT_DEV_CAP_CREDIT_PREALLOCATION.

Signed-off-by: Mattias Rönnblom <mattias.ronnb...@ericsson.com>
---
 drivers/event/dsw/dsw_evdev.c  |  5 ++-
 drivers/event/dsw/dsw_evdev.h  |  6 +++
 drivers/event/dsw/dsw_event.c  | 70 ++++++++++++++++++++++++++++------
 drivers/event/dsw/dsw_xstats.c |  3 ++
 4 files changed, 71 insertions(+), 13 deletions(-)

diff --git a/drivers/event/dsw/dsw_evdev.c b/drivers/event/dsw/dsw_evdev.c
index e819412639..ecc1d947dd 100644
--- a/drivers/event/dsw/dsw_evdev.c
+++ b/drivers/event/dsw/dsw_evdev.c
@@ -228,7 +228,8 @@ dsw_info_get(struct rte_eventdev *dev __rte_unused,
                RTE_EVENT_DEV_CAP_NONSEQ_MODE|
                RTE_EVENT_DEV_CAP_MULTIPLE_QUEUE_PORT|
                RTE_EVENT_DEV_CAP_CARRY_FLOW_ID |
-               RTE_EVENT_DEV_CAP_INDEPENDENT_ENQ
+               RTE_EVENT_DEV_CAP_INDEPENDENT_ENQ |
+               RTE_EVENT_DEV_CAP_CREDIT_PREALLOCATION
        };
 }
 
@@ -458,6 +459,8 @@ dsw_probe(struct rte_vdev_device *vdev)
        dev->enqueue_forward_burst = dsw_event_enqueue_forward_burst;
        dev->dequeue_burst = dsw_event_dequeue_burst;
        dev->maintain = dsw_event_maintain;
+       dev->credit_alloc = dsw_event_credit_alloc;
+       dev->credit_free = dsw_event_credit_free;
 
        if (rte_eal_process_type() != RTE_PROC_PRIMARY)
                return 0;
diff --git a/drivers/event/dsw/dsw_evdev.h b/drivers/event/dsw/dsw_evdev.h
index d78c5f4f26..c026b0a135 100644
--- a/drivers/event/dsw/dsw_evdev.h
+++ b/drivers/event/dsw/dsw_evdev.h
@@ -208,6 +208,7 @@ struct __rte_cache_aligned dsw_port {
 
        uint64_t enqueue_calls;
        uint64_t new_enqueued;
+       uint64_t new_prealloced_enqueued;
        uint64_t forward_enqueued;
        uint64_t release_enqueued;
        uint64_t queue_enqueued[DSW_MAX_QUEUES];
@@ -284,6 +285,11 @@ uint16_t dsw_event_dequeue_burst(void *port, struct 
rte_event *events,
                                 uint16_t num, uint64_t wait);
 void dsw_event_maintain(void *port, int op);
 
+int dsw_event_credit_alloc(void *port, unsigned int new_event_threshold,
+                          unsigned int num_credits);
+
+int dsw_event_credit_free(void *port, unsigned int num_credits);
+
 int dsw_xstats_get_names(const struct rte_eventdev *dev,
                         enum rte_event_dev_xstats_mode mode,
                         uint8_t queue_port_id,
diff --git a/drivers/event/dsw/dsw_event.c b/drivers/event/dsw/dsw_event.c
index 399d9f050e..09f353b324 100644
--- a/drivers/event/dsw/dsw_event.c
+++ b/drivers/event/dsw/dsw_event.c
@@ -93,9 +93,11 @@ dsw_port_return_credits(struct dsw_evdev *dsw, struct 
dsw_port *port,
 
 static void
 dsw_port_enqueue_stats(struct dsw_port *port, uint16_t num_new,
-                      uint16_t num_forward, uint16_t num_release)
+                      uint16_t num_new_prealloced, uint16_t num_forward,
+                      uint16_t num_release)
 {
        port->new_enqueued += num_new;
+       port->new_prealloced_enqueued += num_new_prealloced;
        port->forward_enqueued += num_forward;
        port->release_enqueued += num_release;
 }
@@ -1322,12 +1324,26 @@ dsw_port_flush_out_buffers(struct dsw_evdev *dsw, 
struct dsw_port *source_port)
                dsw_port_transmit_buffered(dsw, source_port, dest_port_id);
 }
 
+static inline bool
+dsw_should_backpressure(struct dsw_evdev *dsw, int32_t new_event_threshold)
+{
+       int32_t credits_on_loan;
+       bool over_threshold;
+
+       credits_on_loan = rte_atomic_load_explicit(&dsw->credits_on_loan,
+                                                  rte_memory_order_relaxed);
+
+       over_threshold = credits_on_loan > new_event_threshold;
+
+       return over_threshold;
+}
+
 static __rte_always_inline uint16_t
 dsw_event_enqueue_burst_generic(struct dsw_port *source_port,
                                const struct rte_event events[],
                                uint16_t events_len, bool op_types_known,
-                               uint16_t num_new, uint16_t num_forward,
-                               uint16_t num_release)
+                               uint16_t num_new, uint16_t num_new_prealloced,
+                               uint16_t num_forward, uint16_t num_release)
 {
        struct dsw_evdev *dsw = source_port->dsw;
        bool enough_credits;
@@ -1364,6 +1380,9 @@ dsw_event_enqueue_burst_generic(struct dsw_port 
*source_port,
                        case RTE_EVENT_OP_NEW:
                                num_new++;
                                break;
+                       case RTE_EVENT_OP_NEW_PREALLOCED:
+                               num_new_prealloced++;
+                               break;
                        case RTE_EVENT_OP_FORWARD:
                                num_forward++;
                                break;
@@ -1379,9 +1398,7 @@ dsw_event_enqueue_burst_generic(struct dsw_port 
*source_port,
         * above the water mark.
         */
        if (unlikely(num_new > 0 &&
-                    rte_atomic_load_explicit(&dsw->credits_on_loan,
-                                             rte_memory_order_relaxed) >
-                    source_port->new_event_threshold))
+                    dsw_should_backpressure(dsw, 
source_port->new_event_threshold)))
                return 0;
 
        enough_credits = dsw_port_acquire_credits(dsw, source_port, num_new);
@@ -1397,7 +1414,8 @@ dsw_event_enqueue_burst_generic(struct dsw_port 
*source_port,
        RTE_VERIFY(num_forward + num_release <= source_port->pending_releases);
        source_port->pending_releases -= (num_forward + num_release);
 
-       dsw_port_enqueue_stats(source_port, num_new, num_forward, num_release);
+       dsw_port_enqueue_stats(source_port, num_new, num_new_prealloced,
+                              num_forward, num_release);
 
        for (i = 0; i < events_len; i++) {
                const struct rte_event *event = &events[i];
@@ -1409,9 +1427,9 @@ dsw_event_enqueue_burst_generic(struct dsw_port 
*source_port,
        }
 
        DSW_LOG_DP_PORT_LINE(DEBUG, source_port->id, "%d non-release events "
-                       "accepted.", num_new + num_forward);
+                       "accepted.", num_new + num_new_prealloced + 
num_forward);
 
-       return (num_new + num_forward + num_release);
+       return (num_new + num_new_prealloced + num_forward + num_release);
 }
 
 uint16_t
@@ -1424,7 +1442,7 @@ dsw_event_enqueue_burst(void *port, const struct 
rte_event events[],
                events_len = source_port->enqueue_depth;
 
        return dsw_event_enqueue_burst_generic(source_port, events,
-                                              events_len, false, 0, 0, 0);
+                                              events_len, false, 0, 0, 0, 0);
 }
 
 uint16_t
@@ -1438,7 +1456,7 @@ dsw_event_enqueue_new_burst(void *port, const struct 
rte_event events[],
 
        return dsw_event_enqueue_burst_generic(source_port, events,
                                               events_len, true, events_len,
-                                              0, 0);
+                                              0, 0, 0);
 }
 
 uint16_t
@@ -1451,7 +1469,7 @@ dsw_event_enqueue_forward_burst(void *port, const struct 
rte_event events[],
                events_len = source_port->enqueue_depth;
 
        return dsw_event_enqueue_burst_generic(source_port, events,
-                                              events_len, true, 0,
+                                              events_len, true, 0, 0,
                                               events_len, 0);
 }
 
@@ -1604,3 +1622,31 @@ void dsw_event_maintain(void *port, int op)
        if (op & RTE_EVENT_DEV_MAINT_OP_FLUSH)
                dsw_port_flush_out_buffers(dsw, source_port);
 }
+
+int dsw_event_credit_alloc(void *port, unsigned int new_event_threshold,
+                          unsigned int num_credits)
+{
+       struct dsw_port *source_port = port;
+       struct dsw_evdev *dsw = source_port->dsw;
+       bool enough_credits;
+
+       if (dsw_should_backpressure(dsw, new_event_threshold))
+               return 0;
+
+       enough_credits = dsw_port_acquire_credits(dsw, source_port, 
num_credits);
+
+       if (!enough_credits)
+               return 0;
+
+       return num_credits;
+}
+
+int dsw_event_credit_free(void *port, unsigned int num_credits)
+{
+       struct dsw_port *source_port = port;
+       struct dsw_evdev *dsw = source_port->dsw;
+
+       dsw_port_return_credits(dsw, source_port, num_credits);
+
+       return 0;
+}
diff --git a/drivers/event/dsw/dsw_xstats.c b/drivers/event/dsw/dsw_xstats.c
index f61dfd80a8..2b58c26cb8 100644
--- a/drivers/event/dsw/dsw_xstats.c
+++ b/drivers/event/dsw/dsw_xstats.c
@@ -65,6 +65,7 @@ static struct dsw_xstat_dev dsw_dev_xstats[] = {
        }
 
 DSW_GEN_PORT_ACCESS_FN(new_enqueued)
+DSW_GEN_PORT_ACCESS_FN(new_prealloced_enqueued)
 DSW_GEN_PORT_ACCESS_FN(forward_enqueued)
 DSW_GEN_PORT_ACCESS_FN(release_enqueued)
 
@@ -136,6 +137,8 @@ DSW_GEN_PORT_ACCESS_FN(last_bg)
 static struct dsw_xstats_port dsw_port_xstats[] = {
        { "port_%u_new_enqueued", dsw_xstats_port_get_new_enqueued,
          false },
+       { "port_%u_new_prealloced_enqueued",
+         dsw_xstats_port_get_new_prealloced_enqueued, false },
        { "port_%u_forward_enqueued", dsw_xstats_port_get_forward_enqueued,
          false },
        { "port_%u_release_enqueued", dsw_xstats_port_get_release_enqueued,
-- 
2.43.0

Reply via email to