@@ -1598,31 +1598,36 @@ rte_sched_port_update_queue_stats_on_drop(struct rte_sched_subport *subport,
#ifdef RTE_SCHED_RED
static inline int
-rte_sched_port_red_drop(struct rte_sched_port *port, struct rte_mbuf *pkt, uint32_t qindex, uint16_t qlen)
+rte_sched_port_red_drop(struct rte_sched_subport *subport,
+ struct rte_mbuf *pkt,
+ uint32_t qindex,
+ uint16_t qlen,
+ uint64_t time)
{
struct rte_sched_queue_extra *qe;
struct rte_red_config *red_cfg;
struct rte_red *red;
uint32_t tc_index;
- enum rte_meter_color color;
+ enum rte_color color;
- tc_index = (qindex >> 2) & 0x3;
+ tc_index = rte_mbuf_sched_traffic_class_get(pkt);
color = rte_sched_port_pkt_read_color(pkt);
- red_cfg = &port->red_config[tc_index][color];
+ red_cfg = &subport->red_config[tc_index][color];
if ((red_cfg->min_th | red_cfg->max_th) == 0)
return 0;
- qe = port->queue_extra + qindex;
+ qe = subport->queue_extra + qindex;
red = &qe->red;
- return rte_red_enqueue(red_cfg, red, qlen, port->time);
+ return rte_red_enqueue(red_cfg, red, qlen, time);
}
static inline void
-rte_sched_port_set_queue_empty_timestamp(struct rte_sched_port *port, uint32_t qindex)
+rte_sched_port_set_queue_empty_timestamp(struct rte_sched_port *port,
+ struct rte_sched_subport *subport, uint32_t qindex)
{
- struct rte_sched_queue_extra *qe = port->queue_extra + qindex;
+ struct rte_sched_queue_extra *qe = subport->queue_extra + qindex;
struct rte_red *red = &qe->red;
rte_red_mark_queue_empty(red, port->time);
@@ -1630,10 +1635,23 @@ rte_sched_port_set_queue_empty_timestamp(struct rte_sched_port *port, uint32_t q
#else
-#define rte_sched_port_red_drop(port, pkt, qindex, qlen) 0
-
-#define rte_sched_port_set_queue_empty_timestamp(port, qindex)
+static inline int rte_sched_port_red_drop(
+ struct rte_sched_subport *subport __rte_unused,
+ struct rte_mbuf *pkt __rte_unused,
+ uint32_t qindex __rte_unused,
+ uint16_t qlen __rte_unused,
+ uint64_t time __rte_unused)
+{
+ return 0;
+}
+static inline void
+rte_sched_port_set_queue_empty_timestamp(struct rte_sched_port *port __rte_unused,
+ struct rte_sched_subport *subport __rte_unused,
+ uint32_t qindex __rte_unused)
+{
+ return;
+}
#endif /* RTE_SCHED_RED */
#ifdef RTE_SCHED_DEBUG
@@ -1665,63 +1683,71 @@ debug_check_queue_slab(struct rte_sched_port *port, uint32_t bmp_pos,
#endif /* RTE_SCHED_DEBUG */
+static inline struct rte_sched_subport *
+rte_sched_port_get_subport(struct rte_sched_port *port,
+ struct rte_mbuf *pkt)
+{
+ uint32_t qindex = rte_mbuf_sched_queue_get(pkt);
+ uint32_t subport_id = (qindex >> (port->max_subport_pipes_log2 + 4)) &
+ (port->n_subports_per_port - 1);
+
+ return port->subports[subport_id];
+}
+
static inline uint32_t
-rte_sched_port_enqueue_qptrs_prefetch0(struct rte_sched_port *port,
- struct rte_mbuf *pkt)
+rte_sched_port_enqueue_qptrs_prefetch0(struct rte_sched_subport *subport,
+ struct rte_mbuf *pkt, uint32_t bitwidth)
{
struct rte_sched_queue *q;
#ifdef RTE_SCHED_COLLECT_STATS
struct rte_sched_queue_extra *qe;
#endif
uint32_t qindex = rte_mbuf_sched_queue_get(pkt);
+ uint32_t queue_id = ((1 << (bitwidth + 4)) - 1) & qindex;
- q = port->queue + qindex;
+ q = subport->queue + queue_id;
rte_prefetch0(q);
#ifdef RTE_SCHED_COLLECT_STATS
- qe = port->queue_extra + qindex;
+ qe = subport->queue_extra + queue_id;
rte_prefetch0(qe);
#endif
- return qindex;
+ return queue_id;
}
static inline void
-rte_sched_port_enqueue_qwa_prefetch0(struct rte_sched_port *port,
+rte_sched_port_enqueue_qwa_prefetch0(struct rte_sched_subport *subport,
uint32_t qindex, struct rte_mbuf **qbase)
{
struct rte_sched_queue *q;
struct rte_mbuf **q_qw;
uint16_t qsize;
- q = port->queue + qindex;
- qsize = rte_sched_port_qsize(port, qindex);
+ q = subport->queue + qindex;
+ qsize = rte_sched_subport_qsize(subport, qindex);
q_qw = qbase + (q->qw & (qsize - 1));
rte_prefetch0(q_qw);
- rte_bitmap_prefetch0(port->bmp, qindex);
+ rte_bitmap_prefetch0(subport->bmp, qindex);
}
static inline int
-rte_sched_port_enqueue_qwa(struct rte_sched_port *port, uint32_t qindex,
- struct rte_mbuf **qbase, struct rte_mbuf *pkt)
+rte_sched_port_enqueue_qwa(struct rte_sched_subport *subport, uint32_t qindex,
+ struct rte_mbuf **qbase, struct rte_mbuf *pkt, uint64_t time)
{
- struct rte_sched_queue *q;
- uint16_t qsize;
- uint16_t qlen;
-
- q = port->queue + qindex;
- qsize = rte_sched_port_qsize(port, qindex);
- qlen = q->qw - q->qr;
+ struct rte_sched_queue *q = subport->queue + qindex;
+ uint16_t qsize = rte_sched_subport_qsize(subport, qindex);
+ uint16_t qlen = q->qw - q->qr;
/* Drop the packet (and update drop stats) when queue is full */
- if (unlikely(rte_sched_port_red_drop(port, pkt, qindex, qlen) ||
- (qlen >= qsize))) {
+ if (unlikely(rte_sched_port_red_drop(subport, pkt, qindex, qlen, time)
+ || (qlen >= qsize))) {
rte_pktmbuf_free(pkt);
#ifdef RTE_SCHED_COLLECT_STATS
- rte_sched_port_update_subport_stats_on_drop(port, qindex, pkt,
- qlen < qsize);
- rte_sched_port_update_queue_stats_on_drop(port, qindex, pkt,
- qlen < qsize);
+ rte_sched_port_update_subport_stats_on_drop(subport, pkt,
+ qlen < qsize);
+ rte_sched_port_update_queue_stats_on_drop(subport, qindex, pkt,
+ qlen < qsize);
#endif
return 0;
}
@@ -1730,13 +1756,13 @@ rte_sched_port_enqueue_qwa(struct rte_sched_port *port, uint32_t qindex,
qbase[q->qw & (qsize - 1)] = pkt;
q->qw++;
- /* Activate queue in the port bitmap */
- rte_bitmap_set(port->bmp, qindex);
+ /* Activate queue in the subport bitmap */
+ rte_bitmap_set(subport->bmp, qindex);
/* Statistics */
#ifdef RTE_SCHED_COLLECT_STATS
- rte_sched_port_update_subport_stats(port, qindex, pkt);
- rte_sched_port_update_queue_stats(port, qindex, pkt);
+ rte_sched_port_update_subport_stats(subport, pkt);
+ rte_sched_port_update_queue_stats(subport, qindex, pkt);
#endif
return 1;
@@ -1764,17 +1790,21 @@ rte_sched_port_enqueue(struct rte_sched_port *port, struct rte_mbuf **pkts,
*pkt30, *pkt31, *pkt_last;
struct rte_mbuf **q00_base, **q01_base, **q10_base, **q11_base,
**q20_base, **q21_base, **q30_base, **q31_base, **q_last_base;
+ struct rte_sched_subport *subport00, *subport01, *subport10, *subport11,
+ *subport20, *subport21, *subport30, *subport31, *subport_last;
uint32_t q00, q01, q10, q11, q20, q21, q30, q31, q_last;
uint32_t r00, r01, r10, r11, r20, r21, r30, r31, r_last;
- uint32_t result, i;
+ uint32_t result, bitwidth, i;
result = 0;
+ bitwidth = port->max_subport_pipes_log2;
/*
* Less then 6 input packets available, which is not enough to
* feed the pipeline
*/
if (unlikely(n_pkts < 6)) {
+ struct rte_sched_subport *subports[5];
struct rte_mbuf **q_base[5];
uint32_t q[5];
@@ -1782,22 +1812,27 @@ rte_sched_port_enqueue(struct rte_sched_port *port, struct rte_mbuf **pkts,
for (i = 0; i < n_pkts; i++)
rte_prefetch0(pkts[i]);
+ /* Prefetch the subport structure for each packet */
+ for (i = 0; i < n_pkts; i++)
+ subports[i] =
+ rte_sched_port_get_subport(port, pkts[i]);
+
/* Prefetch the queue structure for each queue */
for (i = 0; i < n_pkts; i++)
- q[i] = rte_sched_port_enqueue_qptrs_prefetch0(port,
- pkts[i]);
+ q[i] = rte_sched_port_enqueue_qptrs_prefetch0(subports[i],
+ pkts[i], bitwidth);
/* Prefetch the write pointer location of each queue */
for (i = 0; i < n_pkts; i++) {
- q_base[i] = rte_sched_port_qbase(port, q[i]);
- rte_sched_port_enqueue_qwa_prefetch0(port, q[i],
+ q_base[i] = rte_sched_subport_qbase(subports[i], q[i]);
+ rte_sched_port_enqueue_qwa_prefetch0(subports[i], q[i],
q_base[i]);
}
/* Write each packet to its queue */
for (i = 0; i < n_pkts; i++)
- result += rte_sched_port_enqueue_qwa(port, q[i],
- q_base[i], pkts[i]);
+ result += rte_sched_port_enqueue_qwa(subports[i], q[i],
+ q_base[i], pkts[i], port->time);
return result;
}
@@ -1813,21 +1848,25 @@ rte_sched_port_enqueue(struct rte_sched_port *port, struct rte_mbuf **pkts,
rte_prefetch0(pkt10);
rte_prefetch0(pkt11);
- q20 = rte_sched_port_enqueue_qptrs_prefetch0(port, pkt20);
- q21 = rte_sched_port_enqueue_qptrs_prefetch0(port, pkt21);
+ subport20 = rte_sched_port_get_subport(port, pkt20);
+ subport21 = rte_sched_port_get_subport(port, pkt21);
+ q20 = rte_sched_port_enqueue_qptrs_prefetch0(subport20, pkt20, bitwidth);
+ q21 = rte_sched_port_enqueue_qptrs_prefetch0(subport21, pkt21, bitwidth);
pkt00 = pkts[4];
pkt01 = pkts[5];
rte_prefetch0(pkt00);
rte_prefetch0(pkt01);
- q10 = rte_sched_port_enqueue_qptrs_prefetch0(port, pkt10);
- q11 = rte_sched_port_enqueue_qptrs_prefetch0(port, pkt11);
+ subport10 = rte_sched_port_get_subport(port, pkt10);
+ subport11 = rte_sched_port_get_subport(port, pkt11);
+ q10 = rte_sched_port_enqueue_qptrs_prefetch0(subport10, pkt10, bitwidth);
+ q11 = rte_sched_port_enqueue_qptrs_prefetch0(subport11, pkt11, bitwidth);
- q20_base = rte_sched_port_qbase(port, q20);
- q21_base = rte_sched_port_qbase(port, q21);
- rte_sched_port_enqueue_qwa_prefetch0(port, q20, q20_base);
- rte_sched_port_enqueue_qwa_prefetch0(port, q21, q21_base);
+ q20_base = rte_sched_subport_qbase(subport20, q20);
+ q21_base = rte_sched_subport_qbase(subport21, q21);
+ rte_sched_port_enqueue_qwa_prefetch0(subport20, q20, q20_base);
+ rte_sched_port_enqueue_qwa_prefetch0(subport21, q21, q21_base);
/* Run the pipeline */
for (i = 6; i < (n_pkts & (~1)); i += 2) {
@@ -1842,6 +1881,10 @@ rte_sched_port_enqueue(struct rte_sched_port *port, struct rte_mbuf **pkts,
q31 = q21;
q20 = q10;
q21 = q11;
+ subport30 = subport20;
+ subport31 = subport21;
+ subport20 = subport10;
+ subport21 = subport11;
q30_base = q20_base;
q31_base = q21_base;
@@ -1851,19 +1894,25 @@ rte_sched_port_enqueue(struct rte_sched_port *port, struct rte_mbuf **pkts,
rte_prefetch0(pkt00);
rte_prefetch0(pkt01);
- /* Stage 1: Prefetch queue structure storing queue pointers */
- q10 = rte_sched_port_enqueue_qptrs_prefetch0(port, pkt10);
- q11 = rte_sched_port_enqueue_qptrs_prefetch0(port, pkt11);
+ /* Stage 1: Prefetch subport and queue structure storing queue
+ * pointers
+ */
+ subport10 = rte_sched_port_get_subport(port, pkt10);
+ subport11 = rte_sched_port_get_subport(port, pkt11);
+ q10 = rte_sched_port_enqueue_qptrs_prefetch0(subport10, pkt10, bitwidth);
+ q11 = rte_sched_port_enqueue_qptrs_prefetch0(subport11, pkt11, bitwidth);
/* Stage 2: Prefetch queue write location */
- q20_base = rte_sched_port_qbase(port, q20);
- q21_base = rte_sched_port_qbase(port, q21);
- rte_sched_port_enqueue_qwa_prefetch0(port, q20, q20_base);
- rte_sched_port_enqueue_qwa_prefetch0(port, q21, q21_base);
+ q20_base = rte_sched_subport_qbase(subport20, q20);
+ q21_base = rte_sched_subport_qbase(subport21, q21);
+ rte_sched_port_enqueue_qwa_prefetch0(subport20, q20, q20_base);
+ rte_sched_port_enqueue_qwa_prefetch0(subport21, q21, q21_base);
/* Stage 3: Write packet to queue and activate queue */
- r30 = rte_sched_port_enqueue_qwa(port, q30, q30_base, pkt30);
- r31 = rte_sched_port_enqueue_qwa(port, q31, q31_base, pkt31);
+ r30 = rte_sched_port_enqueue_qwa(subport30, q30, q30_base,
+ pkt30, port->time);
+ r31 = rte_sched_port_enqueue_qwa(subport31, q31, q31_base,
+ pkt31, port->time);
result += r30 + r31;
}
@@ -1875,38 +1924,49 @@ rte_sched_port_enqueue(struct rte_sched_port *port, struct rte_mbuf **pkts,
pkt_last = pkts[n_pkts - 1];
rte_prefetch0(pkt_last);
- q00 = rte_sched_port_enqueue_qptrs_prefetch0(port, pkt00);
- q01 = rte_sched_port_enqueue_qptrs_prefetch0(port, pkt01);
+ subport00 = rte_sched_port_get_subport(port, pkt00);
+ subport01 = rte_sched_port_get_subport(port, pkt01);
+ q00 = rte_sched_port_enqueue_qptrs_prefetch0(subport00, pkt00, bitwidth);
+ q01 = rte_sched_port_enqueue_qptrs_prefetch0(subport01, pkt01, bitwidth);
- q10_base = rte_sched_port_qbase(port, q10);
- q11_base = rte_sched_port_qbase(port, q11);
- rte_sched_port_enqueue_qwa_prefetch0(port, q10, q10_base);
- rte_sched_port_enqueue_qwa_prefetch0(port, q11, q11_base);
+ q10_base = rte_sched_subport_qbase(subport10, q10);
+ q11_base = rte_sched_subport_qbase(subport11, q11);
+ rte_sched_port_enqueue_qwa_prefetch0(subport10, q10, q10_base);
+ rte_sched_port_enqueue_qwa_prefetch0(subport11, q11, q11_base);
- r20 = rte_sched_port_enqueue_qwa(port, q20, q20_base, pkt20);
- r21 = rte_sched_port_enqueue_qwa(port, q21, q21_base, pkt21);
+ r20 = rte_sched_port_enqueue_qwa(subport20, q20, q20_base, pkt20,
+ port->time);
+ r21 = rte_sched_port_enqueue_qwa(subport21, q21, q21_base, pkt21,
+ port->time);
result += r20 + r21;
- q_last = rte_sched_port_enqueue_qptrs_prefetch0(port, pkt_last);
+ subport_last = rte_sched_port_get_subport(port, pkt_last);
+ q_last = rte_sched_port_enqueue_qptrs_prefetch0(subport_last,
+ pkt_last, bitwidth);
- q00_base = rte_sched_port_qbase(port, q00);
- q01_base = rte_sched_port_qbase(port, q01);
- rte_sched_port_enqueue_qwa_prefetch0(port, q00, q00_base);
- rte_sched_port_enqueue_qwa_prefetch0(port, q01, q01_base);
+ q00_base = rte_sched_subport_qbase(subport00, q00);
+ q01_base = rte_sched_subport_qbase(subport01, q01);
+ rte_sched_port_enqueue_qwa_prefetch0(subport00, q00, q00_base);
+ rte_sched_port_enqueue_qwa_prefetch0(subport01, q01, q01_base);
- r10 = rte_sched_port_enqueue_qwa(port, q10, q10_base, pkt10);
- r11 = rte_sched_port_enqueue_qwa(port, q11, q11_base, pkt11);
+ r10 = rte_sched_port_enqueue_qwa(subport10, q10, q10_base, pkt10,
+ port->time);
+ r11 = rte_sched_port_enqueue_qwa(subport11, q11, q11_base, pkt11,
+ port->time);
result += r10 + r11;
- q_last_base = rte_sched_port_qbase(port, q_last);
- rte_sched_port_enqueue_qwa_prefetch0(port, q_last, q_last_base);
+ q_last_base = rte_sched_subport_qbase(subport_last, q_last);
+ rte_sched_port_enqueue_qwa_prefetch0(subport_last, q_last, q_last_base);
- r00 = rte_sched_port_enqueue_qwa(port, q00, q00_base, pkt00);
- r01 = rte_sched_port_enqueue_qwa(port, q01, q01_base, pkt01);
+ r00 = rte_sched_port_enqueue_qwa(subport00, q00, q00_base, pkt00,
+ port->time);
+ r01 = rte_sched_port_enqueue_qwa(subport01, q01, q01_base, pkt01,
+ port->time);
result += r00 + r01;
if (n_pkts & 1) {
- r_last = rte_sched_port_enqueue_qwa(port, q_last, q_last_base, pkt_last);
+ r_last = rte_sched_port_enqueue_qwa(subport_last, q_last,
+ q_last_base, pkt_last, port->time);
result += r_last;
}
@@ -2148,7 +2208,7 @@ grinder_schedule(struct rte_sched_port *port, uint32_t pos)
rte_bitmap_clear(port->bmp, qindex);
grinder->qmask &= ~(1 << grinder->qpos);
grinder->wrr_mask[grinder->qpos] = 0;
- rte_sched_port_set_queue_empty_timestamp(port, qindex);
+ rte_sched_port_set_queue_empty_timestamp(port, port->subport, qindex);
}
/* Reset pipe loop detection */