patches for DPDK stable branches
 help / color / mirror / Atom feed
From: Kevin Traynor <ktraynor@redhat.com>
To: "Mattias Rönnblom" <mattias.ronnblom@ericsson.com>
Cc: dpdk stable <stable@dpdk.org>
Subject: patch 'event/dsw: fix flow migration' has been queued to stable release 21.11.3
Date: Tue, 25 Oct 2022 16:06:22 +0100	[thread overview]
Message-ID: <20221025150734.142189-27-ktraynor@redhat.com> (raw)
In-Reply-To: <20221025150734.142189-1-ktraynor@redhat.com>

Hi,

FYI, your patch has been queued to stable release 21.11.3

Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet.
It will be pushed if I get no objections before 11/01/22. So please
shout if anyone has objections.

Also note that after the patch there's a diff of the upstream commit vs the
patch applied to the branch. This will indicate if there was any rebasing
needed to apply to the stable branch. If there were code changes for rebasing
(ie: not only metadata diffs), please double check that the rebase was
correctly done.

Queued patches are on a temporary branch at:
https://github.com/kevintraynor/dpdk-stable

This queued commit can be viewed at:
https://github.com/kevintraynor/dpdk-stable/commit/6dc1d114cd00c1eb22781df48d9fb4d6690948f0

Thanks.

Kevin

---
From 6dc1d114cd00c1eb22781df48d9fb4d6690948f0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mattias=20R=C3=B6nnblom?= <mattias.ronnblom@ericsson.com>
Date: Thu, 7 Jul 2022 13:43:25 +0200
Subject: [PATCH] event/dsw: fix flow migration
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

[ upstream commit 70cb0278a4c52a857fb56cda2183e2ee3fa2633a ]

Fix bug in flow migration, which under certain conditions causes
reordering and violation of atomicity guarantees.

The issue occurs when the processing of a flow (on an atomic queue)
has resulted in events enqueued to a flow currently being migrated,
and the former (producer) flow is also selected for migration. The
events are buffered ("paused") on the originating port, and released
(forwarded) when the migration has completed. However, at the time of
"unpausing" the latter (consumer) flow, processing of the producer
flow on the port to which it was migrated may have already produced
events, for the same paused flow. This constitutes a race condition,
and depending on which port wins, reordering may have been introduced.

This patch forbids migration when a port has paused events, since
those events may have been the result of processing a to-be-migrated
flow.

This patch also disallows processing events pertaining to a flow under
migration, for the same reason. A new buffer is introduced, which
holds such not-yet-processed events dequeued from the port's input
ring. Such events are forwarded to the target port as a part of the
migration process.

The 'forwarding' migration state is eliminated, and instead background
processing is only performed if there are no unreleased events on the
port.

The bug is primarily triggered in situations where multiple flows are
migrated as one transaction, but may occur even if only a single flow
is migrated (e.g., with older DSW versions, which does not support
multi-flow migration).

Fixes: f6257b22e767 ("event/dsw: add load balancing")

Signed-off-by: Mattias Rönnblom <mattias.ronnblom@ericsson.com>
---
 drivers/event/dsw/dsw_evdev.h |   8 +-
 drivers/event/dsw/dsw_event.c | 315 ++++++++++++++++++++++++----------
 2 files changed, 232 insertions(+), 91 deletions(-)

diff --git a/drivers/event/dsw/dsw_evdev.h b/drivers/event/dsw/dsw_evdev.h
index c907c00c78..df7dcc5577 100644
--- a/drivers/event/dsw/dsw_evdev.h
+++ b/drivers/event/dsw/dsw_evdev.h
@@ -129,5 +129,4 @@ enum dsw_migration_state {
 	DSW_MIGRATION_STATE_IDLE,
 	DSW_MIGRATION_STATE_PAUSING,
-	DSW_MIGRATION_STATE_FORWARDING,
 	DSW_MIGRATION_STATE_UNPAUSING
 };
@@ -193,4 +192,11 @@ struct dsw_port {
 	struct rte_event paused_events[DSW_MAX_EVENTS];
 
+	uint16_t emigrating_events_len;
+	/* Buffer for not-yet-processed events pertaining to a flow
+	 * emigrating from this port. These events will be forwarded
+	 * to the target port.
+	 */
+	struct rte_event emigrating_events[DSW_MAX_EVENTS];
+
 	uint16_t seen_events_len;
 	uint16_t seen_events_idx;
diff --git a/drivers/event/dsw/dsw_event.c b/drivers/event/dsw/dsw_event.c
index e209cd5b00..c5fb0c8882 100644
--- a/drivers/event/dsw/dsw_event.c
+++ b/drivers/event/dsw/dsw_event.c
@@ -238,4 +238,13 @@ dsw_port_is_flow_paused(struct dsw_port *port, uint8_t queue_id,
 }
 
+static __rte_always_inline bool
+dsw_port_is_flow_migrating(struct dsw_port *port, uint8_t queue_id,
+			   uint16_t flow_hash)
+{
+	return dsw_is_queue_flow_in_ary(port->emigration_target_qfs,
+					port->emigration_targets_len,
+					queue_id, flow_hash);
+}
+
 static void
 dsw_port_add_paused_flows(struct dsw_port *port, struct dsw_queue_flow *qfs,
@@ -272,7 +281,17 @@ dsw_port_remove_paused_flow(struct dsw_port *port,
 					port->paused_flows[last_idx];
 			port->paused_flows_len--;
-			break;
+
+			DSW_LOG_DP_PORT(DEBUG, port->id,
+					"Unpausing queue_id %d flow_hash %d.\n",
+					target_qf->queue_id,
+					target_qf->flow_hash);
+
+			return;
 		}
 	}
+
+	DSW_LOG_DP_PORT(ERR, port->id,
+			"Failed to unpause queue_id %d flow_hash %d.\n",
+			target_qf->queue_id, target_qf->flow_hash);
 }
 
@@ -285,5 +304,4 @@ dsw_port_remove_paused_flows(struct dsw_port *port,
 	for (i = 0; i < qfs_len; i++)
 		dsw_port_remove_paused_flow(port, &qfs[i]);
-
 }
 
@@ -440,12 +458,13 @@ dsw_is_serving_port(struct dsw_evdev *dsw, uint8_t port_id, uint8_t queue_id)
 static bool
 dsw_select_emigration_target(struct dsw_evdev *dsw,
-			    struct dsw_queue_flow_burst *bursts,
-			    uint16_t num_bursts, uint8_t source_port_id,
-			    int16_t *port_loads, uint16_t num_ports,
-			    uint8_t *target_port_ids,
-			    struct dsw_queue_flow *target_qfs,
-			    uint8_t *targets_len)
+			     struct dsw_port *source_port,
+			     struct dsw_queue_flow_burst *bursts,
+			     uint16_t num_bursts,
+			     int16_t *port_loads, uint16_t num_ports,
+			     uint8_t *target_port_ids,
+			     struct dsw_queue_flow *target_qfs,
+			     uint8_t *targets_len)
 {
-	int16_t source_port_load = port_loads[source_port_id];
+	int16_t source_port_load = port_loads[source_port->id];
 	struct dsw_queue_flow *candidate_qf = NULL;
 	uint8_t candidate_port_id = 0;
@@ -472,5 +491,5 @@ dsw_select_emigration_target(struct dsw_evdev *dsw,
 			int16_t weight;
 
-			if (port_id == source_port_id)
+			if (port_id == source_port->id)
 				continue;
 
@@ -494,5 +513,5 @@ dsw_select_emigration_target(struct dsw_evdev *dsw,
 		return false;
 
-	DSW_LOG_DP_PORT(DEBUG, source_port_id, "Selected queue_id %d "
+	DSW_LOG_DP_PORT(DEBUG, source_port->id, "Selected queue_id %d "
 			"flow_hash %d (with flow load %d) for migration "
 			"to port %d.\n", candidate_qf->queue_id,
@@ -502,5 +521,5 @@ dsw_select_emigration_target(struct dsw_evdev *dsw,
 
 	port_loads[candidate_port_id] += candidate_flow_load;
-	port_loads[source_port_id] -= candidate_flow_load;
+	port_loads[source_port->id] -= candidate_flow_load;
 
 	target_port_ids[*targets_len] = candidate_port_id;
@@ -528,6 +547,6 @@ dsw_select_emigration_targets(struct dsw_evdev *dsw,
 		bool found;
 
-		found = dsw_select_emigration_target(dsw, bursts, num_bursts,
-						     source_port->id,
+		found = dsw_select_emigration_target(dsw, source_port,
+						     bursts, num_bursts,
 						     port_loads, dsw->num_ports,
 						     target_port_ids,
@@ -609,4 +628,5 @@ dsw_port_buffer_paused(struct dsw_port *port,
 }
 
+
 static void
 dsw_port_buffer_non_paused(struct dsw_evdev *dsw, struct dsw_port *source_port,
@@ -680,11 +700,9 @@ dsw_port_buffer_event(struct dsw_evdev *dsw, struct dsw_port *source_port,
 
 static void
-dsw_port_flush_paused_events(struct dsw_evdev *dsw,
-			     struct dsw_port *source_port,
-			     const struct dsw_queue_flow *qf)
+dsw_port_flush_no_longer_paused_events(struct dsw_evdev *dsw,
+				       struct dsw_port *source_port)
 {
 	uint16_t paused_events_len = source_port->paused_events_len;
 	struct rte_event paused_events[paused_events_len];
-	uint8_t dest_port_id;
 	uint16_t i;
 
@@ -692,7 +710,4 @@ dsw_port_flush_paused_events(struct dsw_evdev *dsw,
 		return;
 
-	if (dsw_port_is_flow_paused(source_port, qf->queue_id, qf->flow_hash))
-		return;
-
 	rte_memcpy(paused_events, source_port->paused_events,
 		   paused_events_len * sizeof(struct rte_event));
@@ -700,6 +715,4 @@ dsw_port_flush_paused_events(struct dsw_evdev *dsw,
 	source_port->paused_events_len = 0;
 
-	dest_port_id = dsw_schedule(dsw, qf->queue_id, qf->flow_hash);
-
 	for (i = 0; i < paused_events_len; i++) {
 		struct rte_event *event = &paused_events[i];
@@ -708,10 +721,16 @@ dsw_port_flush_paused_events(struct dsw_evdev *dsw,
 		flow_hash = dsw_flow_id_hash(event->flow_id);
 
-		if (event->queue_id == qf->queue_id &&
-		    flow_hash == qf->flow_hash)
+		if (dsw_port_is_flow_paused(source_port, event->queue_id,
+					    flow_hash))
+			dsw_port_buffer_paused(source_port, event);
+		else {
+			uint8_t dest_port_id;
+
+			dest_port_id = dsw_schedule(dsw, event->queue_id,
+						    flow_hash);
+
 			dsw_port_buffer_non_paused(dsw, source_port,
 						   dest_port_id, event);
-		else
-			dsw_port_buffer_paused(source_port, event);
+		}
 	}
 }
@@ -756,9 +775,4 @@ dsw_port_end_emigration(struct dsw_evdev *dsw, struct dsw_port *port,
 				"queue_id %d flow_hash %d.\n", queue_id,
 				flow_hash);
-
-		if (queue_schedule_type == RTE_SCHED_TYPE_ATOMIC) {
-			dsw_port_remove_paused_flow(port, qf);
-			dsw_port_flush_paused_events(dsw, port, qf);
-		}
 	}
 
@@ -827,9 +841,30 @@ dsw_port_consider_emigration(struct dsw_evdev *dsw,
 		return;
 
-	if (seen_events_len < DSW_MAX_EVENTS_RECORDED)
-		return;
-
 	DSW_LOG_DP_PORT(DEBUG, source_port->id, "Considering emigration.\n");
 
+	if (seen_events_len < DSW_MAX_EVENTS_RECORDED) {
+		DSW_LOG_DP_PORT(DEBUG, source_port->id, "Not enough events "
+				"are recorded to allow for a migration.\n");
+		return;
+	}
+
+	/* A flow migration cannot be initiated if there are paused
+	 * events, since some/all of those events may be have been
+	 * produced as a result of processing the flow(s) selected for
+	 * migration. Moving such a flow would potentially introduced
+	 * reordering, since processing the migrated flow on the
+	 * receiving flow may commence before the to-be-enqueued-to
+
+	 * flows are unpaused, leading to paused events on the second
+	 * port as well, destined for the same paused flow(s). When
+	 * those flows are unpaused, the resulting events are
+	 * delivered the owning port in an undefined order.
+	 */
+	if (source_port->paused_events_len > 0) {
+		DSW_LOG_DP_PORT(DEBUG, source_port->id, "There are "
+				"events in the paus buffer.\n");
+		return;
+	}
+
 	/* Randomize interval to avoid having all threads considering
 	 * emigration at the same in point in time, which might lead
@@ -928,7 +963,6 @@ dsw_port_consider_emigration(struct dsw_evdev *dsw,
 
 static void
-dsw_port_flush_paused_events(struct dsw_evdev *dsw,
-			     struct dsw_port *source_port,
-			     const struct dsw_queue_flow *qf);
+dsw_port_flush_no_longer_paused_events(struct dsw_evdev *dsw,
+				       struct dsw_port *source_port);
 
 static void
@@ -955,18 +989,69 @@ dsw_port_handle_unpause_flows(struct dsw_evdev *dsw, struct dsw_port *port,
 		if (dsw_schedule(dsw, qf->queue_id, qf->flow_hash) == port->id)
 			port->immigrations++;
+	}
+
+	dsw_port_flush_no_longer_paused_events(dsw, port);
+}
+
+static void
+dsw_port_buffer_in_buffer(struct dsw_port *port,
+			  const struct rte_event *event)
+
+{
+	RTE_ASSERT(port->in_buffer_start == 0);
+
+	port->in_buffer[port->in_buffer_len] = *event;
+	port->in_buffer_len++;
+}
 
-		dsw_port_flush_paused_events(dsw, port, qf);
+static void
+dsw_port_forward_emigrated_event(struct dsw_evdev *dsw,
+				 struct dsw_port *source_port,
+				 struct rte_event *event)
+{
+	uint16_t i;
+
+	for (i = 0; i < source_port->emigration_targets_len; i++) {
+		struct dsw_queue_flow *qf =
+			&source_port->emigration_target_qfs[i];
+		uint8_t dest_port_id =
+			source_port->emigration_target_port_ids[i];
+		struct dsw_port *dest_port = &dsw->ports[dest_port_id];
+
+		if (event->queue_id == qf->queue_id &&
+		    dsw_flow_id_hash(event->flow_id) == qf->flow_hash) {
+			/* No need to care about bursting forwarded
+			 * events (to the destination port's in_ring),
+			 * since migration doesn't happen very often,
+			 * and also the majority of the dequeued
+			 * events will likely *not* be forwarded.
+			 */
+			while (rte_event_ring_enqueue_burst(dest_port->in_ring,
+							    event, 1,
+							    NULL) != 1)
+				rte_pause();
+			return;
+		}
 	}
+
+	/* Event did not belong to the emigrated flows */
+	dsw_port_buffer_in_buffer(source_port, event);
+}
+
+static void
+dsw_port_stash_migrating_event(struct dsw_port *port,
+			       const struct rte_event *event)
+{
+	port->emigrating_events[port->emigrating_events_len] = *event;
+	port->emigrating_events_len++;
 }
 
-#define FORWARD_BURST_SIZE (32)
+#define DRAIN_DEQUEUE_BURST_SIZE (32)
 
 static void
-dsw_port_forward_emigrated_flow(struct dsw_port *source_port,
-				struct rte_event_ring *dest_ring,
-				uint8_t queue_id,
-				uint16_t flow_hash)
+dsw_port_drain_in_ring(struct dsw_port *source_port)
 {
-	uint16_t events_left;
+	uint16_t num_events;
+	uint16_t dequeued;
 
 	/* Control ring message should been seen before the ring count
@@ -975,40 +1060,50 @@ dsw_port_forward_emigrated_flow(struct dsw_port *source_port,
 	rte_smp_rmb();
 
-	events_left = rte_event_ring_count(source_port->in_ring);
+	num_events = rte_event_ring_count(source_port->in_ring);
 
-	while (events_left > 0) {
-		uint16_t in_burst_size =
-			RTE_MIN(FORWARD_BURST_SIZE, events_left);
-		struct rte_event in_burst[in_burst_size];
-		uint16_t in_len;
+	for (dequeued = 0; dequeued < num_events; ) {
+		uint16_t burst_size = RTE_MIN(DRAIN_DEQUEUE_BURST_SIZE,
+					      num_events - dequeued);
+		struct rte_event events[burst_size];
+		uint16_t len;
 		uint16_t i;
 
-		in_len = rte_event_ring_dequeue_burst(source_port->in_ring,
-						      in_burst,
-						      in_burst_size, NULL);
-		/* No need to care about bursting forwarded events (to
-		 * the destination port's in_ring), since migration
-		 * doesn't happen very often, and also the majority of
-		 * the dequeued events will likely *not* be forwarded.
-		 */
-		for (i = 0; i < in_len; i++) {
-			struct rte_event *e = &in_burst[i];
-			if (e->queue_id == queue_id &&
-			    dsw_flow_id_hash(e->flow_id) == flow_hash) {
-				while (rte_event_ring_enqueue_burst(dest_ring,
-								    e, 1,
-								    NULL) != 1)
-					rte_pause();
-			} else {
-				uint16_t last_idx = source_port->in_buffer_len;
-				source_port->in_buffer[last_idx] = *e;
-				source_port->in_buffer_len++;
-			}
+		len = rte_event_ring_dequeue_burst(source_port->in_ring,
+						   events, burst_size,
+						   NULL);
+
+		for (i = 0; i < len; i++) {
+			struct rte_event *event = &events[i];
+			uint16_t flow_hash;
+
+			flow_hash = dsw_flow_id_hash(event->flow_id);
+
+			if (unlikely(dsw_port_is_flow_migrating(source_port,
+								event->queue_id,
+								flow_hash)))
+				dsw_port_stash_migrating_event(source_port,
+							       event);
+			else
+				dsw_port_buffer_in_buffer(source_port, event);
 		}
 
-		events_left -= in_len;
+		dequeued += len;
 	}
 }
 
+static void
+dsw_port_forward_emigrated_flows(struct dsw_evdev *dsw,
+				 struct dsw_port *source_port)
+{
+	uint16_t i;
+
+	for (i = 0; i < source_port->emigrating_events_len; i++) {
+		struct rte_event *event = &source_port->emigrating_events[i];
+
+		dsw_port_forward_emigrated_event(dsw, source_port, event);
+	}
+	source_port->emigrating_events_len = 0;
+}
+
 static void
 dsw_port_move_emigrating_flows(struct dsw_evdev *dsw,
@@ -1019,6 +1114,4 @@ dsw_port_move_emigrating_flows(struct dsw_evdev *dsw,
 	dsw_port_flush_out_buffers(dsw, source_port);
 
-	rte_smp_wmb();
-
 	for (i = 0; i < source_port->emigration_targets_len; i++) {
 		struct dsw_queue_flow *qf =
@@ -1026,13 +1119,20 @@ dsw_port_move_emigrating_flows(struct dsw_evdev *dsw,
 		uint8_t dest_port_id =
 			source_port->emigration_target_port_ids[i];
-		struct dsw_port *dest_port = &dsw->ports[dest_port_id];
 
 		dsw->queues[qf->queue_id].flow_to_port_map[qf->flow_hash] =
-			dest_port_id;
-
-		dsw_port_forward_emigrated_flow(source_port, dest_port->in_ring,
-						qf->queue_id, qf->flow_hash);
+		    dest_port_id;
 	}
 
+	rte_smp_wmb();
+
+	dsw_port_drain_in_ring(source_port);
+	dsw_port_forward_emigrated_flows(dsw, source_port);
+
+	dsw_port_remove_paused_flows(source_port,
+				     source_port->emigration_target_qfs,
+				     source_port->emigration_targets_len);
+
+	dsw_port_flush_no_longer_paused_events(dsw, source_port);
+
 	/* Flow table update and migration destination port's enqueues
 	 * must be seen before the control message.
@@ -1055,7 +1155,5 @@ dsw_port_handle_confirm(struct dsw_evdev *dsw, struct dsw_port *port)
 		switch (port->migration_state) {
 		case DSW_MIGRATION_STATE_PAUSING:
-			DSW_LOG_DP_PORT(DEBUG, port->id, "Going into forwarding "
-					"migration state.\n");
-			port->migration_state = DSW_MIGRATION_STATE_FORWARDING;
+			dsw_port_move_emigrating_flows(dsw, port);
 			break;
 		case DSW_MIGRATION_STATE_UNPAUSING:
@@ -1097,7 +1195,4 @@ static void
 dsw_port_note_op(struct dsw_port *port, uint16_t num_events)
 {
-	/* To pull the control ring reasonably often on busy ports,
-	 * each dequeued/enqueued event is considered an 'op' too.
-	 */
 	port->ops_since_bg_task += (num_events+1);
 }
@@ -1106,7 +1201,10 @@ static void
 dsw_port_bg_process(struct dsw_evdev *dsw, struct dsw_port *port)
 {
-	if (unlikely(port->migration_state == DSW_MIGRATION_STATE_FORWARDING &&
-		     port->pending_releases == 0))
-		dsw_port_move_emigrating_flows(dsw, port);
+	/* For simplicity (in the migration logic), avoid all
+	 * background processing in case event processing is in
+	 * progress.
+	 */
+	if (port->pending_releases > 0)
+		return;
 
 	/* Polling the control ring is relatively inexpensive, and
@@ -1168,5 +1266,5 @@ dsw_event_enqueue_burst_generic(struct dsw_port *source_port,
 
 	DSW_LOG_DP_PORT(DEBUG, source_port->id, "Attempting to enqueue %d "
-			"events to port %d.\n", events_len, source_port->id);
+			"events.\n", events_len);
 
 	dsw_port_bg_process(dsw, source_port);
@@ -1352,4 +1450,36 @@ dsw_port_dequeue_burst(struct dsw_port *port, struct rte_event *events,
 }
 
+static void
+dsw_port_stash_migrating_events(struct dsw_port *port,
+				struct rte_event *events, uint16_t *num)
+{
+	uint16_t i;
+
+	/* The assumption here - performance-wise - is that events
+	 * belonging to migrating flows are relatively rare.
+	 */
+	for (i = 0; i < (*num); ) {
+		struct rte_event *event = &events[i];
+		uint16_t flow_hash;
+
+		flow_hash = dsw_flow_id_hash(event->flow_id);
+
+		if (unlikely(dsw_port_is_flow_migrating(port, event->queue_id,
+							flow_hash))) {
+			uint16_t left;
+
+			dsw_port_stash_migrating_event(port, event);
+
+			(*num)--;
+			left = *num - i;
+
+			if (left > 0)
+				memmove(event, event + 1,
+					left * sizeof(struct rte_event));
+		} else
+			i++;
+	}
+}
+
 uint16_t
 dsw_event_dequeue_burst(void *port, struct rte_event *events, uint16_t num,
@@ -1369,4 +1499,9 @@ dsw_event_dequeue_burst(void *port, struct rte_event *events, uint16_t num,
 	dequeued = dsw_port_dequeue_burst(source_port, events, num);
 
+	if (unlikely(source_port->migration_state ==
+		     DSW_MIGRATION_STATE_PAUSING))
+		dsw_port_stash_migrating_events(source_port, events,
+						&dequeued);
+
 	source_port->pending_releases = dequeued;
 
-- 
2.37.3

---
  Diff of the applied patch vs upstream commit (please double-check if non-empty:
---
--- -	2022-10-25 14:18:59.165388086 +0100
+++ 0027-event-dsw-fix-flow-migration.patch	2022-10-25 14:18:58.382797987 +0100
@@ -1 +1 @@
-From 70cb0278a4c52a857fb56cda2183e2ee3fa2633a Mon Sep 17 00:00:00 2001
+From 6dc1d114cd00c1eb22781df48d9fb4d6690948f0 Mon Sep 17 00:00:00 2001
@@ -8,0 +9,2 @@
+[ upstream commit 70cb0278a4c52a857fb56cda2183e2ee3fa2633a ]
+
@@ -42 +43,0 @@
-Cc: stable@dpdk.org
@@ -73 +74 @@
-index 340561b4e6..9932caf2ee 100644
+index e209cd5b00..c5fb0c8882 100644
@@ -76 +77 @@
-@@ -239,4 +239,13 @@ dsw_port_is_flow_paused(struct dsw_port *port, uint8_t queue_id,
+@@ -238,4 +238,13 @@ dsw_port_is_flow_paused(struct dsw_port *port, uint8_t queue_id,
@@ -90 +91 @@
-@@ -273,7 +282,17 @@ dsw_port_remove_paused_flow(struct dsw_port *port,
+@@ -272,7 +281,17 @@ dsw_port_remove_paused_flow(struct dsw_port *port,
@@ -109 +110 @@
-@@ -286,5 +305,4 @@ dsw_port_remove_paused_flows(struct dsw_port *port,
+@@ -285,5 +304,4 @@ dsw_port_remove_paused_flows(struct dsw_port *port,
@@ -115 +116 @@
-@@ -441,12 +459,13 @@ dsw_is_serving_port(struct dsw_evdev *dsw, uint8_t port_id, uint8_t queue_id)
+@@ -440,12 +458,13 @@ dsw_is_serving_port(struct dsw_evdev *dsw, uint8_t port_id, uint8_t queue_id)
@@ -136 +137 @@
-@@ -473,5 +492,5 @@ dsw_select_emigration_target(struct dsw_evdev *dsw,
+@@ -472,5 +491,5 @@ dsw_select_emigration_target(struct dsw_evdev *dsw,
@@ -143 +144 @@
-@@ -495,5 +514,5 @@ dsw_select_emigration_target(struct dsw_evdev *dsw,
+@@ -494,5 +513,5 @@ dsw_select_emigration_target(struct dsw_evdev *dsw,
@@ -150 +151 @@
-@@ -503,5 +522,5 @@ dsw_select_emigration_target(struct dsw_evdev *dsw,
+@@ -502,5 +521,5 @@ dsw_select_emigration_target(struct dsw_evdev *dsw,
@@ -157 +158 @@
-@@ -529,6 +548,6 @@ dsw_select_emigration_targets(struct dsw_evdev *dsw,
+@@ -528,6 +547,6 @@ dsw_select_emigration_targets(struct dsw_evdev *dsw,
@@ -166 +167 @@
-@@ -610,4 +629,5 @@ dsw_port_buffer_paused(struct dsw_port *port,
+@@ -609,4 +628,5 @@ dsw_port_buffer_paused(struct dsw_port *port,
@@ -172 +173 @@
-@@ -681,11 +701,9 @@ dsw_port_buffer_event(struct dsw_evdev *dsw, struct dsw_port *source_port,
+@@ -680,11 +700,9 @@ dsw_port_buffer_event(struct dsw_evdev *dsw, struct dsw_port *source_port,
@@ -186 +187 @@
-@@ -693,7 +711,4 @@ dsw_port_flush_paused_events(struct dsw_evdev *dsw,
+@@ -692,7 +710,4 @@ dsw_port_flush_paused_events(struct dsw_evdev *dsw,
@@ -194 +195 @@
-@@ -701,6 +716,4 @@ dsw_port_flush_paused_events(struct dsw_evdev *dsw,
+@@ -700,6 +715,4 @@ dsw_port_flush_paused_events(struct dsw_evdev *dsw,
@@ -201 +202 @@
-@@ -709,10 +722,16 @@ dsw_port_flush_paused_events(struct dsw_evdev *dsw,
+@@ -708,10 +721,16 @@ dsw_port_flush_paused_events(struct dsw_evdev *dsw,
@@ -222 +223 @@
-@@ -757,9 +776,4 @@ dsw_port_end_emigration(struct dsw_evdev *dsw, struct dsw_port *port,
+@@ -756,9 +775,4 @@ dsw_port_end_emigration(struct dsw_evdev *dsw, struct dsw_port *port,
@@ -232 +233 @@
-@@ -828,9 +842,30 @@ dsw_port_consider_emigration(struct dsw_evdev *dsw,
+@@ -827,9 +841,30 @@ dsw_port_consider_emigration(struct dsw_evdev *dsw,
@@ -266 +267 @@
-@@ -929,7 +964,6 @@ dsw_port_consider_emigration(struct dsw_evdev *dsw,
+@@ -928,7 +963,6 @@ dsw_port_consider_emigration(struct dsw_evdev *dsw,
@@ -276 +277 @@
-@@ -956,18 +990,69 @@ dsw_port_handle_unpause_flows(struct dsw_evdev *dsw, struct dsw_port *port,
+@@ -955,18 +989,69 @@ dsw_port_handle_unpause_flows(struct dsw_evdev *dsw, struct dsw_port *port,
@@ -353 +354 @@
-@@ -976,40 +1061,50 @@ dsw_port_forward_emigrated_flow(struct dsw_port *source_port,
+@@ -975,40 +1060,50 @@ dsw_port_forward_emigrated_flow(struct dsw_port *source_port,
@@ -432 +433 @@
-@@ -1020,6 +1115,4 @@ dsw_port_move_emigrating_flows(struct dsw_evdev *dsw,
+@@ -1019,6 +1114,4 @@ dsw_port_move_emigrating_flows(struct dsw_evdev *dsw,
@@ -439 +440 @@
-@@ -1027,13 +1120,20 @@ dsw_port_move_emigrating_flows(struct dsw_evdev *dsw,
+@@ -1026,13 +1119,20 @@ dsw_port_move_emigrating_flows(struct dsw_evdev *dsw,
@@ -465 +466 @@
-@@ -1056,7 +1156,5 @@ dsw_port_handle_confirm(struct dsw_evdev *dsw, struct dsw_port *port)
+@@ -1055,7 +1155,5 @@ dsw_port_handle_confirm(struct dsw_evdev *dsw, struct dsw_port *port)
@@ -474 +475 @@
-@@ -1098,7 +1196,4 @@ static void
+@@ -1097,7 +1195,4 @@ static void
@@ -482 +483 @@
-@@ -1107,7 +1202,10 @@ static void
+@@ -1106,7 +1201,10 @@ static void
@@ -496 +497 @@
-@@ -1169,5 +1267,5 @@ dsw_event_enqueue_burst_generic(struct dsw_port *source_port,
+@@ -1168,5 +1266,5 @@ dsw_event_enqueue_burst_generic(struct dsw_port *source_port,
@@ -503 +504 @@
-@@ -1353,4 +1451,36 @@ dsw_port_dequeue_burst(struct dsw_port *port, struct rte_event *events,
+@@ -1352,4 +1450,36 @@ dsw_port_dequeue_burst(struct dsw_port *port, struct rte_event *events,
@@ -540 +541 @@
-@@ -1370,4 +1500,9 @@ dsw_event_dequeue_burst(void *port, struct rte_event *events, uint16_t num,
+@@ -1369,4 +1499,9 @@ dsw_event_dequeue_burst(void *port, struct rte_event *events, uint16_t num,


  parent reply	other threads:[~2022-10-25 15:08 UTC|newest]

Thread overview: 101+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-25 15:05 patch 'build: enable developer mode for all working trees' " Kevin Traynor
2022-10-25 15:05 ` patch 'net: accept unaligned data in checksum routines' " Kevin Traynor
2022-10-25 15:05 ` patch 'eal: fix side effect in some pointer arithmetic macros' " Kevin Traynor
2022-10-25 15:05 ` patch 'app/testpmd: restore ixgbe bypass commands' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/bonding: fix array overflow in Rx burst' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/bonding: fix double slave link status query' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/failsafe: fix interrupt handle leak' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/nfp: compose firmware file name with new hwinfo' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/axgbe: fix scattered Rx' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/axgbe: fix mbuf lengths in " Kevin Traynor
2022-10-25 15:06 ` patch 'net/axgbe: fix length of each segment " Kevin Traynor
2022-10-25 15:06 ` patch 'net/axgbe: fix checksum and RSS " Kevin Traynor
2022-10-25 15:06 ` patch 'net/axgbe: optimise " Kevin Traynor
2022-10-25 15:06 ` patch 'net/axgbe: remove freeing buffer in " Kevin Traynor
2022-10-25 15:06 ` patch 'net/nfp: improve HW info header log readability' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/txgbe: fix IPv6 flow rule' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/txgbe: remove semaphore between SW/FW' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/txgbe: rename some extended statistics' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/ngbe: " Kevin Traynor
2022-10-25 15:06 ` patch 'net/ngbe: remove semaphore between SW/FW' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/ngbe: fix maximum frame size' " Kevin Traynor
2022-10-25 15:06 ` patch 'common/cnxk: fix log level during MCAM allocation' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/mvneta: fix build with GCC 12' " Kevin Traynor
2022-10-25 15:06 ` patch 'common/cnxk: fix missing flow counter reset' " Kevin Traynor
2022-10-25 15:06 ` patch 'common/cnxk: fix printing disabled MKEX registers' " Kevin Traynor
2022-10-25 15:06 ` patch 'malloc: fix storage size for some allocations' " Kevin Traynor
2022-10-25 15:06 ` Kevin Traynor [this message]
2022-10-25 15:06 ` patch 'event/sw: fix device name in dump' " Kevin Traynor
2022-10-25 15:06 ` patch 'eventdev/eth_tx: add spinlock for adapter start/stop' " Kevin Traynor
2022-10-25 15:06 ` patch 'eventdev/eth_tx: fix adapter stop' " Kevin Traynor
2022-10-25 15:06 ` patch 'test/ipsec: skip if no compatible device' " Kevin Traynor
2022-10-25 15:06 ` patch 'examples/ipsec-secgw: use Tx checksum offload conditionally' " Kevin Traynor
2022-10-25 15:06 ` patch 'test/crypto: fix debug messages' " Kevin Traynor
2022-10-25 15:06 ` patch 'common/qat: fix VF to PF answer' " Kevin Traynor
2022-10-25 15:06 ` patch 'test/ipsec: fix build with GCC 12' " Kevin Traynor
2022-10-25 15:06 ` patch 'ipsec: " Kevin Traynor
2022-10-25 15:06 ` patch 'crypto/qat: " Kevin Traynor
2022-10-25 15:06 ` patch 'cryptodev: fix missing SHA3 algorithm strings' " Kevin Traynor
2022-10-25 15:06 ` patch 'eventdev: fix name of Rx conf type in documentation' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/i40e: fix VF representor release' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/ice: fix RSS hash update' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/ice/base: fix inner symmetric RSS hash in raw flow' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/iavf: fix L3 checksum Tx offload flag' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/iavf: fix VLAN insertion' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/iavf: fix pattern check for flow director parser' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/iavf: fix Tx done descriptors cleanup' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/iavf: update IPsec ESN values when updating session' " Kevin Traynor
2022-10-25 15:06 ` patch 'common/iavf: avoid copy in async mode' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/ice/base: fix division during E822 PTP init' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/ice/base: fix 100M speed capability' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/ice/base: fix DSCP PFC TLV creation' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/ice/base: fix media type of PHY 10G SFI C2C' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/ice/base: fix function descriptions for parser' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/ice/base: fix endian format' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/ice/base: fix array overflow in add switch recipe' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/ice/base: fix bit finding range over ptype bitmap' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/ice/base: fix add MAC rule' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/ice/base: fix double VLAN in promiscuous mode' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/ice/base: ignore promiscuous already exist' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/ice/base: fix input set of GTPoGRE' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/iavf: fix processing VLAN TCI in SSE path' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/iavf: fix outer checksum flags' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/virtio: fix crash when configured twice' " Kevin Traynor
2022-10-25 15:06 ` patch 'net/mlx4: fix Verbs FD leak in secondary process' " Kevin Traynor
2022-10-25 15:07 ` patch 'net/mlx5: " Kevin Traynor
2022-10-25 15:07 ` patch 'net/mlx5: fix check for orphan wait descriptor' " Kevin Traynor
2022-10-25 15:07 ` patch 'net/mlx5: fix single not inline packet storing' " Kevin Traynor
2022-10-25 15:07 ` patch 'net/mlx5: fix inline length exceeding descriptor limit' " Kevin Traynor
2022-10-25 15:07 ` patch 'net/mlx5: fix Tx check for hardware descriptor length' " Kevin Traynor
2022-10-25 15:07 ` patch 'net/mlx5: fix modify action with tunnel decapsulation' " Kevin Traynor
2022-10-25 15:07 ` patch 'net/mlx5: fix meter profile delete after disable' " Kevin Traynor
2022-10-25 15:07 ` patch 'net/iavf: check illegal packet sizes' " Kevin Traynor
2022-10-25 15:07 ` patch 'net/ice: " Kevin Traynor
2022-10-25 15:07 ` patch 'net/cnxk: fix DF bit in vector mode' " Kevin Traynor
2022-10-25 15:07 ` patch 'net/axgbe: reset end of packet in scattered Rx' " Kevin Traynor
2022-10-25 15:07 ` patch 'net/axgbe: clear buffer on scattered Rx chaining failure' " Kevin Traynor
2022-10-25 15:07 ` patch 'net/axgbe: save segment data in scattered Rx' " Kevin Traynor
2022-10-25 15:07 ` patch 'common/sfc_efx/base: fix maximum Tx data count' " Kevin Traynor
2022-10-25 15:07 ` patch 'event/cnxk: fix missing xstats operations' " Kevin Traynor
2022-10-25 15:07 ` patch 'cryptodev: fix unduly newlines in logs' " Kevin Traynor
2022-10-25 15:07 ` patch 'net/bnxt: fix null pointer dereference in LED config' " Kevin Traynor
2022-11-17  9:05   ` 答复: " Mao,Yingming
2022-11-17 10:08     ` Kevin Traynor
2022-10-25 15:07 ` patch 'net/bnxt: fix error code during MTU change' " Kevin Traynor
2022-10-25 15:07 ` patch 'net/bnxt: remove unnecessary check' " Kevin Traynor
2022-10-25 15:07 ` patch 'net/bnxt: fix representor info freeing' " Kevin Traynor
2022-10-25 15:07 ` patch 'net/bnxt: fix build with GCC 13' " Kevin Traynor
2022-10-25 15:07 ` patch 'mem: fix API doc about allocation on secondary processes' " Kevin Traynor
2022-10-25 15:07 ` patch 'examples/vm_power_manager: use safe list iterator' " Kevin Traynor
2022-10-25 15:07 ` patch 'timer: fix stopping all timers' " Kevin Traynor
2022-10-25 15:07 ` patch 'vhost: fix build with GCC 12' " Kevin Traynor
2022-10-25 15:07 ` patch 'net/i40e: fix build with MinGW " Kevin Traynor
2022-10-25 15:07 ` patch 'net/qede/base: fix 32-bit build with " Kevin Traynor
2022-10-25 15:07 ` patch 'net/tap: fix overflow of network interface index' " Kevin Traynor
2022-10-25 15:07 ` patch 'net/memif: fix crash with different number of Rx/Tx queues' " Kevin Traynor
2022-10-25 15:07 ` patch 'common/sfc_efx/base: remove VQ index check during VQ start' " Kevin Traynor
2022-10-25 15:07 ` patch 'net/hns3: fix Rx with PTP' " Kevin Traynor
2022-10-25 15:07 ` patch 'net/hns3: fix crash in SVE Tx' " Kevin Traynor
2022-10-25 15:07 ` patch 'net/hns3: fix next-to-use overflow " Kevin Traynor
2022-10-25 15:07 ` patch 'net/hns3: fix next-to-use overflow in simple " Kevin Traynor
2022-10-25 15:07 ` patch 'net/hns3: fix crash when secondary process access FW' " Kevin Traynor

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=20221025150734.142189-27-ktraynor@redhat.com \
    --to=ktraynor@redhat.com \
    --cc=mattias.ronnblom@ericsson.com \
    --cc=stable@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).