All of lore.kernel.org
 help / color / mirror / Atom feed
* [net-next PATCH v3 0/3] Extend action skbedit to RX queue mapping
@ 2022-10-21  7:58 Amritha Nambiar
  2022-10-21  7:58 ` [net-next PATCH v3 1/3] act_skbedit: skbedit queue mapping for receive queue Amritha Nambiar
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Amritha Nambiar @ 2022-10-21  7:58 UTC (permalink / raw)
  To: netdev, kuba
  Cc: alexander.duyck, jhs, jiri, xiyou.wangcong, vinicius.gomes,
	sridhar.samudrala, amritha.nambiar

Based on the discussion on
https://lore.kernel.org/netdev/166260012413.81018.8010396115034847972.stgit@anambiarhost.jf.intel.com/ ,
the following series extends skbedit tc action to RX queue mapping.
Currently, skbedit action in tc allows overriding of transmit queue.
Extending this ability of skedit action supports the selection of
receive queue for incoming packets. On the receive side, this action
is supported only in hardware, so the skip_sw flag is enforced.

Enabled ice driver to offload this type of filter into the hardware
for accepting packets to the device's receive queue.

v3: Enforced skip_sw so that the action skbedit RX queue mapping is
    hardware only

---

Amritha Nambiar (3):
      act_skbedit: skbedit queue mapping for receive queue
      ice: Enable RX queue selection using skbedit action
      Documentation: networking: TC queue based filtering


 Documentation/networking/index.rst            |    1 
 Documentation/networking/tc-queue-filters.rst |   37 +++
 drivers/net/ethernet/intel/ice/ice.h          |   15 +
 drivers/net/ethernet/intel/ice/ice_main.c     |    2 
 drivers/net/ethernet/intel/ice/ice_tc_lib.c   |  351 ++++++++++++++++++-------
 drivers/net/ethernet/intel/ice/ice_tc_lib.h   |   40 ++-
 include/net/act_api.h                         |    1 
 include/net/flow_offload.h                    |    2 
 include/net/tc_act/tc_skbedit.h               |   29 ++
 net/sched/act_skbedit.c                       |   14 +
 net/sched/cls_api.c                           |    7 
 11 files changed, 388 insertions(+), 111 deletions(-)
 create mode 100644 Documentation/networking/tc-queue-filters.rst

--

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [net-next PATCH v3 1/3] act_skbedit: skbedit queue mapping for receive queue
  2022-10-21  7:58 [net-next PATCH v3 0/3] Extend action skbedit to RX queue mapping Amritha Nambiar
@ 2022-10-21  7:58 ` Amritha Nambiar
  2022-10-26 11:40   ` Roi Dayan
  2022-10-21  7:58 ` [net-next PATCH v3 2/3] ice: Enable RX queue selection using skbedit action Amritha Nambiar
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 11+ messages in thread
From: Amritha Nambiar @ 2022-10-21  7:58 UTC (permalink / raw)
  To: netdev, kuba
  Cc: alexander.duyck, jhs, jiri, xiyou.wangcong, vinicius.gomes,
	sridhar.samudrala, amritha.nambiar

Add support for skbedit queue mapping action on receive
side. This is supported only in hardware, so the skip_sw
flag is enforced. This enables offloading filters for
receive queue selection in the hardware using the
skbedit action. Traffic arrives on the Rx queue requested
in the skbedit action parameter. A new tc action flag
TCA_ACT_FLAGS_AT_INGRESS is introduced to identify the
traffic direction the action queue_mapping is requested
on during filter addition. This is used to disallow
offloading the skbedit queue mapping action on transmit
side.

Example:
$tc filter add dev $IFACE ingress protocol ip flower dst_ip $DST_IP\
 action skbedit queue_mapping $rxq_id skip_sw

Reviewed-by: Sridhar Samudrala <sridhar.samudrala@intel.com>
Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
---
 include/net/act_api.h           |    1 +
 include/net/flow_offload.h      |    2 ++
 include/net/tc_act/tc_skbedit.h |   29 +++++++++++++++++++++++++++++
 net/sched/act_skbedit.c         |   14 ++++++++++++--
 net/sched/cls_api.c             |    7 +++++++
 5 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/include/net/act_api.h b/include/net/act_api.h
index 61f2ceb3939e..c94ea1a306e0 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -67,6 +67,7 @@ struct tc_action {
 #define TCA_ACT_FLAGS_BIND	(1U << (TCA_ACT_FLAGS_USER_BITS + 1))
 #define TCA_ACT_FLAGS_REPLACE	(1U << (TCA_ACT_FLAGS_USER_BITS + 2))
 #define TCA_ACT_FLAGS_NO_RTNL	(1U << (TCA_ACT_FLAGS_USER_BITS + 3))
+#define TCA_ACT_FLAGS_AT_INGRESS	(1U << (TCA_ACT_FLAGS_USER_BITS + 4))
 
 /* Update lastuse only if needed, to avoid dirtying a cache line.
  * We use a temp variable to avoid fetching jiffies twice.
diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h
index e343f9f8363e..7a60bc6d72c9 100644
--- a/include/net/flow_offload.h
+++ b/include/net/flow_offload.h
@@ -155,6 +155,7 @@ enum flow_action_id {
 	FLOW_ACTION_MARK,
 	FLOW_ACTION_PTYPE,
 	FLOW_ACTION_PRIORITY,
+	FLOW_ACTION_RX_QUEUE_MAPPING,
 	FLOW_ACTION_WAKE,
 	FLOW_ACTION_QUEUE,
 	FLOW_ACTION_SAMPLE,
@@ -247,6 +248,7 @@ struct flow_action_entry {
 		u32			csum_flags;	/* FLOW_ACTION_CSUM */
 		u32			mark;		/* FLOW_ACTION_MARK */
 		u16                     ptype;          /* FLOW_ACTION_PTYPE */
+		u16			rx_queue;	/* FLOW_ACTION_RX_QUEUE_MAPPING */
 		u32			priority;	/* FLOW_ACTION_PRIORITY */
 		struct {				/* FLOW_ACTION_QUEUE */
 			u32		ctx;
diff --git a/include/net/tc_act/tc_skbedit.h b/include/net/tc_act/tc_skbedit.h
index dc1079f28e13..9649600fb3dc 100644
--- a/include/net/tc_act/tc_skbedit.h
+++ b/include/net/tc_act/tc_skbedit.h
@@ -95,12 +95,41 @@ static inline u32 tcf_skbedit_priority(const struct tc_action *a)
 	return priority;
 }
 
+static inline u16 tcf_skbedit_rx_queue_mapping(const struct tc_action *a)
+{
+	u16 rx_queue;
+
+	rcu_read_lock();
+	rx_queue = rcu_dereference(to_skbedit(a)->params)->queue_mapping;
+	rcu_read_unlock();
+
+	return rx_queue;
+}
+
 /* Return true iff action is queue_mapping */
 static inline bool is_tcf_skbedit_queue_mapping(const struct tc_action *a)
 {
 	return is_tcf_skbedit_with_flag(a, SKBEDIT_F_QUEUE_MAPPING);
 }
 
+/* Return true if action is on ingress traffic */
+static inline bool is_tcf_skbedit_ingress(u32 flags)
+{
+	return flags & TCA_ACT_FLAGS_AT_INGRESS;
+}
+
+static inline bool is_tcf_skbedit_tx_queue_mapping(const struct tc_action *a)
+{
+	return is_tcf_skbedit_queue_mapping(a) &&
+	       !is_tcf_skbedit_ingress(a->tcfa_flags);
+}
+
+static inline bool is_tcf_skbedit_rx_queue_mapping(const struct tc_action *a)
+{
+	return is_tcf_skbedit_queue_mapping(a) &&
+	       is_tcf_skbedit_ingress(a->tcfa_flags);
+}
+
 /* Return true iff action is inheritdsfield */
 static inline bool is_tcf_skbedit_inheritdsfield(const struct tc_action *a)
 {
diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c
index 7f598784fd30..1710780c908a 100644
--- a/net/sched/act_skbedit.c
+++ b/net/sched/act_skbedit.c
@@ -148,6 +148,11 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla,
 	}
 
 	if (tb[TCA_SKBEDIT_QUEUE_MAPPING] != NULL) {
+		if (is_tcf_skbedit_ingress(act_flags) &&
+		    !(act_flags & TCA_ACT_FLAGS_SKIP_SW)) {
+			NL_SET_ERR_MSG_MOD(extack, "\"queue_mapping\" option on receive side is hardware only, use skip_sw");
+			return -EOPNOTSUPP;
+		}
 		flags |= SKBEDIT_F_QUEUE_MAPPING;
 		queue_mapping = nla_data(tb[TCA_SKBEDIT_QUEUE_MAPPING]);
 	}
@@ -374,9 +379,12 @@ static int tcf_skbedit_offload_act_setup(struct tc_action *act, void *entry_data
 		} else if (is_tcf_skbedit_priority(act)) {
 			entry->id = FLOW_ACTION_PRIORITY;
 			entry->priority = tcf_skbedit_priority(act);
-		} else if (is_tcf_skbedit_queue_mapping(act)) {
-			NL_SET_ERR_MSG_MOD(extack, "Offload not supported when \"queue_mapping\" option is used");
+		} else if (is_tcf_skbedit_tx_queue_mapping(act)) {
+			NL_SET_ERR_MSG_MOD(extack, "Offload not supported when \"queue_mapping\" option is used on transmit side");
 			return -EOPNOTSUPP;
+		} else if (is_tcf_skbedit_rx_queue_mapping(act)) {
+			entry->id = FLOW_ACTION_RX_QUEUE_MAPPING;
+			entry->rx_queue = tcf_skbedit_rx_queue_mapping(act);
 		} else if (is_tcf_skbedit_inheritdsfield(act)) {
 			NL_SET_ERR_MSG_MOD(extack, "Offload not supported when \"inheritdsfield\" option is used");
 			return -EOPNOTSUPP;
@@ -394,6 +402,8 @@ static int tcf_skbedit_offload_act_setup(struct tc_action *act, void *entry_data
 			fl_action->id = FLOW_ACTION_PTYPE;
 		else if (is_tcf_skbedit_priority(act))
 			fl_action->id = FLOW_ACTION_PRIORITY;
+		else if (is_tcf_skbedit_rx_queue_mapping(act))
+			fl_action->id = FLOW_ACTION_RX_QUEUE_MAPPING;
 		else
 			return -EOPNOTSUPP;
 	}
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 50566db45949..23d1cfa4f58c 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -1953,6 +1953,11 @@ static void tfilter_put(struct tcf_proto *tp, void *fh)
 		tp->ops->put(tp, fh);
 }
 
+static bool is_qdisc_ingress(__u32 classid)
+{
+	return (TC_H_MIN(classid) == TC_H_MIN(TC_H_MIN_INGRESS));
+}
+
 static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
 			  struct netlink_ext_ack *extack)
 {
@@ -2144,6 +2149,8 @@ static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
 		flags |= TCA_ACT_FLAGS_REPLACE;
 	if (!rtnl_held)
 		flags |= TCA_ACT_FLAGS_NO_RTNL;
+	if (is_qdisc_ingress(parent))
+		flags |= TCA_ACT_FLAGS_AT_INGRESS;
 	err = tp->ops->change(net, skb, tp, cl, t->tcm_handle, tca, &fh,
 			      flags, extack);
 	if (err == 0) {


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [net-next PATCH v3 2/3] ice: Enable RX queue selection using skbedit action
  2022-10-21  7:58 [net-next PATCH v3 0/3] Extend action skbedit to RX queue mapping Amritha Nambiar
  2022-10-21  7:58 ` [net-next PATCH v3 1/3] act_skbedit: skbedit queue mapping for receive queue Amritha Nambiar
@ 2022-10-21  7:58 ` Amritha Nambiar
  2022-10-21  7:58 ` [net-next PATCH v3 3/3] Documentation: networking: TC queue based filtering Amritha Nambiar
  2022-10-25  9:00 ` [net-next PATCH v3 0/3] Extend action skbedit to RX queue mapping patchwork-bot+netdevbpf
  3 siblings, 0 replies; 11+ messages in thread
From: Amritha Nambiar @ 2022-10-21  7:58 UTC (permalink / raw)
  To: netdev, kuba
  Cc: alexander.duyck, jhs, jiri, xiyou.wangcong, vinicius.gomes,
	sridhar.samudrala, amritha.nambiar

This patch uses TC skbedit queue_mapping action to support
forwarding packets to a device queue. Such filters with action
forward to queue will be the highest priority switch filter in
HW.
Example:
$ tc filter add dev ens4f0 protocol ip ingress flower\
  dst_ip 192.168.1.12 ip_proto tcp dst_port 5001\
  action skbedit queue_mapping 5 skip_sw

The above command adds an ingress filter, incoming packets
qualifying the match will be accepted into queue 5. The queue
number is in decimal format.

Refactored ice_add_tc_flower_adv_fltr() to consolidate code with
action FWD_TO_VSI and FWD_TO QUEUE.

Reviewed-by: Sridhar Samudrala <sridhar.samudrala@intel.com>
Reviewed-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
---
 drivers/net/ethernet/intel/ice/ice.h        |   15 +
 drivers/net/ethernet/intel/ice/ice_main.c   |    2 
 drivers/net/ethernet/intel/ice/ice_tc_lib.c |  351 +++++++++++++++++++--------
 drivers/net/ethernet/intel/ice/ice_tc_lib.h |   40 ++-
 4 files changed, 299 insertions(+), 109 deletions(-)

diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
index 001500afc4a6..d75c8d11f867 100644
--- a/drivers/net/ethernet/intel/ice/ice.h
+++ b/drivers/net/ethernet/intel/ice/ice.h
@@ -137,6 +137,21 @@
  */
 #define ICE_BW_KBPS_DIVISOR		125
 
+/* Default recipes have priority 4 and below, hence priority values between 5..7
+ * can be used as filter priority for advanced switch filter (advanced switch
+ * filters need new recipe to be created for specified extraction sequence
+ * because default recipe extraction sequence does not represent custom
+ * extraction)
+ */
+#define ICE_SWITCH_FLTR_PRIO_QUEUE	7
+/* prio 6 is reserved for future use (e.g. switch filter with L3 fields +
+ * (Optional: IP TOS/TTL) + L4 fields + (optionally: TCP fields such as
+ * SYN/FIN/RST))
+ */
+#define ICE_SWITCH_FLTR_PRIO_RSVD	6
+#define ICE_SWITCH_FLTR_PRIO_VSI	5
+#define ICE_SWITCH_FLTR_PRIO_QGRP	ICE_SWITCH_FLTR_PRIO_VSI
+
 /* Macro for each VSI in a PF */
 #define ice_for_each_vsi(pf, i) \
 	for ((i) = 0; (i) < (pf)->num_alloc_vsi; (i)++)
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index 0f6718719453..df65e829ea33 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -8283,7 +8283,7 @@ static void ice_rem_all_chnl_fltrs(struct ice_pf *pf)
 
 		rule.rid = fltr->rid;
 		rule.rule_id = fltr->rule_id;
-		rule.vsi_handle = fltr->dest_id;
+		rule.vsi_handle = fltr->dest_vsi_handle;
 		status = ice_rem_adv_rule_by_id(&pf->hw, &rule);
 		if (status) {
 			if (status == -ENOENT)
diff --git a/drivers/net/ethernet/intel/ice/ice_tc_lib.c b/drivers/net/ethernet/intel/ice/ice_tc_lib.c
index f68c555be4e9..faba0f857cd9 100644
--- a/drivers/net/ethernet/intel/ice/ice_tc_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_tc_lib.c
@@ -724,13 +724,123 @@ ice_eswitch_add_tc_fltr(struct ice_vsi *vsi, struct ice_tc_flower_fltr *fltr)
 	 */
 	fltr->rid = rule_added.rid;
 	fltr->rule_id = rule_added.rule_id;
-	fltr->dest_id = rule_added.vsi_handle;
+	fltr->dest_vsi_handle = rule_added.vsi_handle;
 
 exit:
 	kfree(list);
 	return ret;
 }
 
+/**
+ * ice_locate_vsi_using_queue - locate VSI using queue (forward to queue action)
+ * @vsi: Pointer to VSI
+ * @tc_fltr: Pointer to tc_flower_filter
+ *
+ * Locate the VSI using specified queue. When ADQ is not enabled, always
+ * return input VSI, otherwise locate corresponding VSI based on per channel
+ * offset and qcount
+ */
+static struct ice_vsi *
+ice_locate_vsi_using_queue(struct ice_vsi *vsi,
+			   struct ice_tc_flower_fltr *tc_fltr)
+{
+	int num_tc, tc, queue;
+
+	/* if ADQ is not active, passed VSI is the candidate VSI */
+	if (!ice_is_adq_active(vsi->back))
+		return vsi;
+
+	/* Locate the VSI (it could still be main PF VSI or CHNL_VSI depending
+	 * upon queue number)
+	 */
+	num_tc = vsi->mqprio_qopt.qopt.num_tc;
+	queue = tc_fltr->action.fwd.q.queue;
+
+	for (tc = 0; tc < num_tc; tc++) {
+		int qcount = vsi->mqprio_qopt.qopt.count[tc];
+		int offset = vsi->mqprio_qopt.qopt.offset[tc];
+
+		if (queue >= offset && queue < offset + qcount) {
+			/* for non-ADQ TCs, passed VSI is the candidate VSI */
+			if (tc < ICE_CHNL_START_TC)
+				return vsi;
+			else
+				return vsi->tc_map_vsi[tc];
+		}
+	}
+	return NULL;
+}
+
+static struct ice_rx_ring *
+ice_locate_rx_ring_using_queue(struct ice_vsi *vsi,
+			       struct ice_tc_flower_fltr *tc_fltr)
+{
+	u16 queue = tc_fltr->action.fwd.q.queue;
+
+	return queue < vsi->num_rxq ? vsi->rx_rings[queue] : NULL;
+}
+
+/**
+ * ice_tc_forward_action - Determine destination VSI and queue for the action
+ * @vsi: Pointer to VSI
+ * @tc_fltr: Pointer to TC flower filter structure
+ *
+ * Validates the tc forward action and determines the destination VSI and queue
+ * for the forward action.
+ */
+static struct ice_vsi *
+ice_tc_forward_action(struct ice_vsi *vsi, struct ice_tc_flower_fltr *tc_fltr)
+{
+	struct ice_rx_ring *ring = NULL;
+	struct ice_vsi *ch_vsi = NULL;
+	struct ice_pf *pf = vsi->back;
+	struct device *dev;
+	u32 tc_class;
+
+	dev = ice_pf_to_dev(pf);
+
+	/* Get the destination VSI and/or destination queue and validate them */
+	switch (tc_fltr->action.fltr_act) {
+	case ICE_FWD_TO_VSI:
+		tc_class = tc_fltr->action.fwd.tc.tc_class;
+		/* Select the destination VSI */
+		if (tc_class < ICE_CHNL_START_TC) {
+			NL_SET_ERR_MSG_MOD(tc_fltr->extack,
+					   "Unable to add filter because of unsupported destination");
+			return ERR_PTR(-EOPNOTSUPP);
+		}
+		/* Locate ADQ VSI depending on hw_tc number */
+		ch_vsi = vsi->tc_map_vsi[tc_class];
+		break;
+	case ICE_FWD_TO_Q:
+		/* Locate the Rx queue */
+		ring = ice_locate_rx_ring_using_queue(vsi, tc_fltr);
+		if (!ring) {
+			dev_err(dev,
+				"Unable to locate Rx queue for action fwd_to_queue: %u\n",
+				tc_fltr->action.fwd.q.queue);
+			return ERR_PTR(-EINVAL);
+		}
+		/* Determine destination VSI even though the action is
+		 * FWD_TO_QUEUE, because QUEUE is associated with VSI
+		 */
+		ch_vsi = tc_fltr->dest_vsi;
+		break;
+	default:
+		dev_err(dev,
+			"Unable to add filter because of unsupported action %u (supported actions: fwd to tc, fwd to queue)\n",
+			tc_fltr->action.fltr_act);
+		return ERR_PTR(-EINVAL);
+	}
+	/* Must have valid ch_vsi (it could be main VSI or ADQ VSI) */
+	if (!ch_vsi) {
+		dev_err(dev,
+			"Unable to add filter because specified destination VSI doesn't exist\n");
+		return ERR_PTR(-EINVAL);
+	}
+	return ch_vsi;
+}
+
 /**
  * ice_add_tc_flower_adv_fltr - add appropriate filter rules
  * @vsi: Pointer to VSI
@@ -772,11 +882,10 @@ ice_add_tc_flower_adv_fltr(struct ice_vsi *vsi,
 		return -EOPNOTSUPP;
 	}
 
-	/* get the channel (aka ADQ VSI) */
-	if (tc_fltr->dest_vsi)
-		ch_vsi = tc_fltr->dest_vsi;
-	else
-		ch_vsi = vsi->tc_map_vsi[tc_fltr->action.tc_class];
+	/* validate forwarding action VSI and queue */
+	ch_vsi = ice_tc_forward_action(vsi, tc_fltr);
+	if (IS_ERR(ch_vsi))
+		return PTR_ERR(ch_vsi);
 
 	lkups_cnt = ice_tc_count_lkups(flags, headers, tc_fltr);
 	list = kcalloc(lkups_cnt, sizeof(*list), GFP_ATOMIC);
@@ -790,30 +899,40 @@ ice_add_tc_flower_adv_fltr(struct ice_vsi *vsi,
 	}
 
 	rule_info.sw_act.fltr_act = tc_fltr->action.fltr_act;
-	if (tc_fltr->action.tc_class >= ICE_CHNL_START_TC) {
-		if (!ch_vsi) {
-			NL_SET_ERR_MSG_MOD(tc_fltr->extack, "Unable to add filter because specified destination doesn't exist");
-			ret = -EINVAL;
-			goto exit;
-		}
+	/* specify the cookie as filter_rule_id */
+	rule_info.fltr_rule_id = tc_fltr->cookie;
 
-		rule_info.sw_act.fltr_act = ICE_FWD_TO_VSI;
+	switch (tc_fltr->action.fltr_act) {
+	case ICE_FWD_TO_VSI:
 		rule_info.sw_act.vsi_handle = ch_vsi->idx;
-		rule_info.priority = 7;
+		rule_info.priority = ICE_SWITCH_FLTR_PRIO_VSI;
 		rule_info.sw_act.src = hw->pf_id;
 		rule_info.rx = true;
 		dev_dbg(dev, "add switch rule for TC:%u vsi_idx:%u, lkups_cnt:%u\n",
-			tc_fltr->action.tc_class,
+			tc_fltr->action.fwd.tc.tc_class,
 			rule_info.sw_act.vsi_handle, lkups_cnt);
-	} else {
+		break;
+	case ICE_FWD_TO_Q:
+		/* HW queue number in global space */
+		rule_info.sw_act.fwd_id.q_id = tc_fltr->action.fwd.q.hw_queue;
+		rule_info.sw_act.vsi_handle = ch_vsi->idx;
+		rule_info.priority = ICE_SWITCH_FLTR_PRIO_QUEUE;
+		rule_info.sw_act.src = hw->pf_id;
+		rule_info.rx = true;
+		dev_dbg(dev, "add switch rule action to forward to queue:%u (HW queue %u), lkups_cnt:%u\n",
+			tc_fltr->action.fwd.q.queue,
+			tc_fltr->action.fwd.q.hw_queue, lkups_cnt);
+		break;
+	default:
 		rule_info.sw_act.flag |= ICE_FLTR_TX;
+		/* In case of Tx (LOOKUP_TX), src needs to be src VSI */
 		rule_info.sw_act.src = vsi->idx;
+		/* 'Rx' is false, direction of rule(LOOKUPTRX) */
 		rule_info.rx = false;
+		rule_info.priority = ICE_SWITCH_FLTR_PRIO_VSI;
+		break;
 	}
 
-	/* specify the cookie as filter_rule_id */
-	rule_info.fltr_rule_id = tc_fltr->cookie;
-
 	ret = ice_add_adv_rule(hw, list, lkups_cnt, &rule_info, &rule_added);
 	if (ret == -EEXIST) {
 		NL_SET_ERR_MSG_MOD(tc_fltr->extack,
@@ -831,19 +950,14 @@ ice_add_tc_flower_adv_fltr(struct ice_vsi *vsi,
 	 */
 	tc_fltr->rid = rule_added.rid;
 	tc_fltr->rule_id = rule_added.rule_id;
-	if (tc_fltr->action.tc_class > 0 && ch_vsi) {
-		/* For PF ADQ, VSI type is set as ICE_VSI_CHNL, and
-		 * for PF ADQ filter, it is not yet set in tc_fltr,
-		 * hence store the dest_vsi ptr in tc_fltr
-		 */
-		if (ch_vsi->type == ICE_VSI_CHNL)
-			tc_fltr->dest_vsi = ch_vsi;
+	tc_fltr->dest_vsi_handle = rule_added.vsi_handle;
+	if (tc_fltr->action.fltr_act == ICE_FWD_TO_VSI ||
+	    tc_fltr->action.fltr_act == ICE_FWD_TO_Q) {
+		tc_fltr->dest_vsi = ch_vsi;
 		/* keep track of advanced switch filter for
-		 * destination VSI (channel VSI)
+		 * destination VSI
 		 */
 		ch_vsi->num_chnl_fltr++;
-		/* in this case, dest_id is VSI handle (sw handle) */
-		tc_fltr->dest_id = rule_added.vsi_handle;
 
 		/* keeps track of channel filters for PF VSI */
 		if (vsi->type == ICE_VSI_PF &&
@@ -851,10 +965,22 @@ ice_add_tc_flower_adv_fltr(struct ice_vsi *vsi,
 			      ICE_TC_FLWR_FIELD_ENC_DST_MAC)))
 			pf->num_dmac_chnl_fltrs++;
 	}
-	dev_dbg(dev, "added switch rule (lkups_cnt %u, flags 0x%x) for TC %u, rid %u, rule_id %u, vsi_idx %u\n",
-		lkups_cnt, flags,
-		tc_fltr->action.tc_class, rule_added.rid,
-		rule_added.rule_id, rule_added.vsi_handle);
+	switch (tc_fltr->action.fltr_act) {
+	case ICE_FWD_TO_VSI:
+		dev_dbg(dev, "added switch rule (lkups_cnt %u, flags 0x%x), action is forward to TC %u, rid %u, rule_id %u, vsi_idx %u\n",
+			lkups_cnt, flags,
+			tc_fltr->action.fwd.tc.tc_class, rule_added.rid,
+			rule_added.rule_id, rule_added.vsi_handle);
+		break;
+	case ICE_FWD_TO_Q:
+		dev_dbg(dev, "added switch rule (lkups_cnt %u, flags 0x%x), action is forward to queue: %u (HW queue %u)     , rid %u, rule_id %u\n",
+			lkups_cnt, flags, tc_fltr->action.fwd.q.queue,
+			tc_fltr->action.fwd.q.hw_queue, rule_added.rid,
+			rule_added.rule_id);
+		break;
+	default:
+		break;
+	}
 exit:
 	kfree(list);
 	return ret;
@@ -1455,43 +1581,15 @@ ice_add_switch_fltr(struct ice_vsi *vsi, struct ice_tc_flower_fltr *fltr)
 }
 
 /**
- * ice_handle_tclass_action - Support directing to a traffic class
+ * ice_prep_adq_filter - Prepare ADQ filter with the required additional headers
  * @vsi: Pointer to VSI
- * @cls_flower: Pointer to TC flower offload structure
  * @fltr: Pointer to TC flower filter structure
  *
- * Support directing traffic to a traffic class
+ * Prepare ADQ filter with the required additional header fields
  */
 static int
-ice_handle_tclass_action(struct ice_vsi *vsi,
-			 struct flow_cls_offload *cls_flower,
-			 struct ice_tc_flower_fltr *fltr)
+ice_prep_adq_filter(struct ice_vsi *vsi, struct ice_tc_flower_fltr *fltr)
 {
-	int tc = tc_classid_to_hwtc(vsi->netdev, cls_flower->classid);
-	struct ice_vsi *main_vsi;
-
-	if (tc < 0) {
-		NL_SET_ERR_MSG_MOD(fltr->extack, "Unable to add filter because specified destination is invalid");
-		return -EINVAL;
-	}
-	if (!tc) {
-		NL_SET_ERR_MSG_MOD(fltr->extack, "Unable to add filter because of invalid destination");
-		return -EINVAL;
-	}
-
-	if (!(vsi->all_enatc & BIT(tc))) {
-		NL_SET_ERR_MSG_MOD(fltr->extack, "Unable to add filter because of non-existence destination");
-		return -EINVAL;
-	}
-
-	/* Redirect to a TC class or Queue Group */
-	main_vsi = ice_get_main_vsi(vsi->back);
-	if (!main_vsi || !main_vsi->netdev) {
-		NL_SET_ERR_MSG_MOD(fltr->extack,
-				   "Unable to add filter because of invalid netdevice");
-		return -EINVAL;
-	}
-
 	if ((fltr->flags & ICE_TC_FLWR_FIELD_TENANT_ID) &&
 	    (fltr->flags & (ICE_TC_FLWR_FIELD_DST_MAC |
 			   ICE_TC_FLWR_FIELD_SRC_MAC))) {
@@ -1503,9 +1601,8 @@ ice_handle_tclass_action(struct ice_vsi *vsi,
 	/* For ADQ, filter must include dest MAC address, otherwise unwanted
 	 * packets with unrelated MAC address get delivered to ADQ VSIs as long
 	 * as remaining filter criteria is satisfied such as dest IP address
-	 * and dest/src L4 port. Following code is trying to handle:
-	 * 1. For non-tunnel, if user specify MAC addresses, use them (means
-	 * this code won't do anything
+	 * and dest/src L4 port. Below code handles the following cases:
+	 * 1. For non-tunnel, if user specify MAC addresses, use them.
 	 * 2. For non-tunnel, if user didn't specify MAC address, add implicit
 	 * dest MAC to be lower netdev's active unicast MAC address
 	 * 3. For tunnel,  as of now TC-filter through flower classifier doesn't
@@ -1528,35 +1625,97 @@ ice_handle_tclass_action(struct ice_vsi *vsi,
 		eth_broadcast_addr(fltr->outer_headers.l2_mask.dst_mac);
 	}
 
-	/* validate specified dest MAC address, make sure either it belongs to
-	 * lower netdev or any of MACVLAN. MACVLANs MAC address are added as
-	 * unicast MAC filter destined to main VSI.
-	 */
-	if (!ice_mac_fltr_exist(&main_vsi->back->hw,
-				fltr->outer_headers.l2_key.dst_mac,
-				main_vsi->idx)) {
-		NL_SET_ERR_MSG_MOD(fltr->extack,
-				   "Unable to add filter because legacy MAC filter for specified destination doesn't exist");
-		return -EINVAL;
-	}
-
 	/* Make sure VLAN is already added to main VSI, before allowing ADQ to
 	 * add a VLAN based filter such as MAC + VLAN + L4 port.
 	 */
 	if (fltr->flags & ICE_TC_FLWR_FIELD_VLAN) {
 		u16 vlan_id = be16_to_cpu(fltr->outer_headers.vlan_hdr.vlan_id);
 
-		if (!ice_vlan_fltr_exist(&main_vsi->back->hw, vlan_id,
-					 main_vsi->idx)) {
+		if (!ice_vlan_fltr_exist(&vsi->back->hw, vlan_id, vsi->idx)) {
 			NL_SET_ERR_MSG_MOD(fltr->extack,
 					   "Unable to add filter because legacy VLAN filter for specified destination doesn't exist");
 			return -EINVAL;
 		}
 	}
+	return 0;
+}
+
+/**
+ * ice_handle_tclass_action - Support directing to a traffic class
+ * @vsi: Pointer to VSI
+ * @cls_flower: Pointer to TC flower offload structure
+ * @fltr: Pointer to TC flower filter structure
+ *
+ * Support directing traffic to a traffic class/queue-set
+ */
+static int
+ice_handle_tclass_action(struct ice_vsi *vsi,
+			 struct flow_cls_offload *cls_flower,
+			 struct ice_tc_flower_fltr *fltr)
+{
+	int tc = tc_classid_to_hwtc(vsi->netdev, cls_flower->classid);
+
+	/* user specified hw_tc (must be non-zero for ADQ TC), action is forward
+	 * to hw_tc (i.e. ADQ channel number)
+	 */
+	if (tc < ICE_CHNL_START_TC) {
+		NL_SET_ERR_MSG_MOD(fltr->extack,
+				   "Unable to add filter because of unsupported destination");
+		return -EOPNOTSUPP;
+	}
+	if (!(vsi->all_enatc & BIT(tc))) {
+		NL_SET_ERR_MSG_MOD(fltr->extack,
+				   "Unable to add filter because of non-existence destination");
+		return -EINVAL;
+	}
 	fltr->action.fltr_act = ICE_FWD_TO_VSI;
-	fltr->action.tc_class = tc;
+	fltr->action.fwd.tc.tc_class = tc;
 
-	return 0;
+	return ice_prep_adq_filter(vsi, fltr);
+}
+
+static int
+ice_tc_forward_to_queue(struct ice_vsi *vsi, struct ice_tc_flower_fltr *fltr,
+			struct flow_action_entry *act)
+{
+	struct ice_vsi *ch_vsi = NULL;
+	u16 queue = act->rx_queue;
+
+	if (queue > vsi->num_rxq) {
+		NL_SET_ERR_MSG_MOD(fltr->extack,
+				   "Unable to add filter because specified queue is invalid");
+		return -EINVAL;
+	}
+	fltr->action.fltr_act = ICE_FWD_TO_Q;
+	fltr->action.fwd.q.queue = queue;
+	/* determine corresponding HW queue */
+	fltr->action.fwd.q.hw_queue = vsi->rxq_map[queue];
+
+	/* If ADQ is configured, and the queue belongs to ADQ VSI, then prepare
+	 * ADQ switch filter
+	 */
+	ch_vsi = ice_locate_vsi_using_queue(vsi, fltr);
+	if (!ch_vsi)
+		return -EINVAL;
+	fltr->dest_vsi = ch_vsi;
+	if (!ice_is_chnl_fltr(fltr))
+		return 0;
+
+	return ice_prep_adq_filter(vsi, fltr);
+}
+
+static int
+ice_tc_parse_action(struct ice_vsi *vsi, struct ice_tc_flower_fltr *fltr,
+		    struct flow_action_entry *act)
+{
+	switch (act->id) {
+	case FLOW_ACTION_RX_QUEUE_MAPPING:
+		/* forward to queue */
+		return ice_tc_forward_to_queue(vsi, fltr, act);
+	default:
+		NL_SET_ERR_MSG_MOD(fltr->extack, "Unsupported TC action");
+		return -EOPNOTSUPP;
+	}
 }
 
 /**
@@ -1575,7 +1734,7 @@ ice_parse_tc_flower_actions(struct ice_vsi *vsi,
 	struct flow_rule *rule = flow_cls_offload_flow_rule(cls_flower);
 	struct flow_action *flow_action = &rule->action;
 	struct flow_action_entry *act;
-	int i;
+	int i, err;
 
 	if (cls_flower->classid)
 		return ice_handle_tclass_action(vsi, cls_flower, fltr);
@@ -1584,21 +1743,13 @@ ice_parse_tc_flower_actions(struct ice_vsi *vsi,
 		return -EINVAL;
 
 	flow_action_for_each(i, act, flow_action) {
-		if (ice_is_eswitch_mode_switchdev(vsi->back)) {
-			int err = ice_eswitch_tc_parse_action(fltr, act);
-
-			if (err)
-				return err;
-			continue;
-		}
-		/* Allow only one rule per filter */
-
-		/* Drop action */
-		if (act->id == FLOW_ACTION_DROP) {
-			NL_SET_ERR_MSG_MOD(fltr->extack, "Unsupported action DROP");
-			return -EINVAL;
-		}
-		fltr->action.fltr_act = ICE_FWD_TO_VSI;
+		if (ice_is_eswitch_mode_switchdev(vsi->back))
+			err = ice_eswitch_tc_parse_action(fltr, act);
+		else
+			err = ice_tc_parse_action(vsi, fltr, act);
+		if (err)
+			return err;
+		continue;
 	}
 	return 0;
 }
@@ -1618,7 +1769,7 @@ static int ice_del_tc_fltr(struct ice_vsi *vsi, struct ice_tc_flower_fltr *fltr)
 
 	rule_rem.rid = fltr->rid;
 	rule_rem.rule_id = fltr->rule_id;
-	rule_rem.vsi_handle = fltr->dest_id;
+	rule_rem.vsi_handle = fltr->dest_vsi_handle;
 	err = ice_rem_adv_rule_by_id(&pf->hw, &rule_rem);
 	if (err) {
 		if (err == -ENOENT) {
diff --git a/drivers/net/ethernet/intel/ice/ice_tc_lib.h b/drivers/net/ethernet/intel/ice/ice_tc_lib.h
index 92642faad595..d916d1e92aa3 100644
--- a/drivers/net/ethernet/intel/ice/ice_tc_lib.h
+++ b/drivers/net/ethernet/intel/ice/ice_tc_lib.h
@@ -45,7 +45,20 @@ struct ice_indr_block_priv {
 };
 
 struct ice_tc_flower_action {
-	u32 tc_class;
+	/* forward action specific params */
+	union {
+		struct {
+			u32 tc_class; /* forward to hw_tc */
+			u32 rsvd;
+		} tc;
+		struct {
+			u16 queue; /* forward to queue */
+			/* To add filter in HW, absolute queue number in global
+			 * space of queues (between 0...N) is needed
+			 */
+			u16 hw_queue;
+		} q;
+	} fwd;
 	enum ice_sw_fwd_act_type fltr_act;
 };
 
@@ -131,11 +144,11 @@ struct ice_tc_flower_fltr {
 	 */
 	u16 rid;
 	u16 rule_id;
-	/* this could be queue/vsi_idx (sw handle)/queue_group, depending upon
-	 * destination type
+	/* VSI handle of the destination VSI (it could be main PF VSI, CHNL_VSI,
+	 * VF VSI)
 	 */
-	u16 dest_id;
-	/* if dest_id is vsi_idx, then need to store destination VSI ptr */
+	u16 dest_vsi_handle;
+	/* ptr to destination VSI */
 	struct ice_vsi *dest_vsi;
 	/* direction of fltr for eswitch use case */
 	enum ice_eswitch_fltr_direction direction;
@@ -162,12 +175,23 @@ struct ice_tc_flower_fltr {
  * @f: Pointer to tc-flower filter
  *
  * Criteria to determine of given filter is valid channel filter
- * or not is based on its "destination". If destination is hw_tc (aka tc_class)
- * and it is non-zero, then it is valid channel (aka ADQ) filter
+ * or not is based on its destination.
+ * For forward to VSI action, if destination is valid hw_tc (aka tc_class)
+ * and in supported range of TCs for ADQ, then return true.
+ * For forward to queue, as long as dest_vsi is valid and it is of type
+ * VSI_CHNL (PF ADQ VSI is of type VSI_CHNL), return true.
+ * NOTE: For forward to queue, correct dest_vsi is still set in tc_fltr based
+ * on destination queue specified.
  */
 static inline bool ice_is_chnl_fltr(struct ice_tc_flower_fltr *f)
 {
-	return !!f->action.tc_class;
+	if (f->action.fltr_act == ICE_FWD_TO_VSI)
+		return f->action.fwd.tc.tc_class >= ICE_CHNL_START_TC &&
+		       f->action.fwd.tc.tc_class < ICE_CHNL_MAX_TC;
+	else if (f->action.fltr_act == ICE_FWD_TO_Q)
+		return f->dest_vsi && f->dest_vsi->type == ICE_VSI_CHNL;
+
+	return false;
 }
 
 /**


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [net-next PATCH v3 3/3] Documentation: networking: TC queue based filtering
  2022-10-21  7:58 [net-next PATCH v3 0/3] Extend action skbedit to RX queue mapping Amritha Nambiar
  2022-10-21  7:58 ` [net-next PATCH v3 1/3] act_skbedit: skbedit queue mapping for receive queue Amritha Nambiar
  2022-10-21  7:58 ` [net-next PATCH v3 2/3] ice: Enable RX queue selection using skbedit action Amritha Nambiar
@ 2022-10-21  7:58 ` Amritha Nambiar
  2022-10-25  9:00 ` [net-next PATCH v3 0/3] Extend action skbedit to RX queue mapping patchwork-bot+netdevbpf
  3 siblings, 0 replies; 11+ messages in thread
From: Amritha Nambiar @ 2022-10-21  7:58 UTC (permalink / raw)
  To: netdev, kuba
  Cc: alexander.duyck, jhs, jiri, xiyou.wangcong, vinicius.gomes,
	sridhar.samudrala, amritha.nambiar

Add tc-queue-filters.rst with notes on TC filters for
selecting a set of queues and/or a queue.

Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
---
 Documentation/networking/index.rst            |    1 +
 Documentation/networking/tc-queue-filters.rst |   37 +++++++++++++++++++++++++
 2 files changed, 38 insertions(+)
 create mode 100644 Documentation/networking/tc-queue-filters.rst

diff --git a/Documentation/networking/index.rst b/Documentation/networking/index.rst
index 16a153bcc5fe..4f2d1f682a18 100644
--- a/Documentation/networking/index.rst
+++ b/Documentation/networking/index.rst
@@ -104,6 +104,7 @@ Contents:
    switchdev
    sysfs-tagging
    tc-actions-env-rules
+   tc-queue-filters
    tcp-thin
    team
    timestamping
diff --git a/Documentation/networking/tc-queue-filters.rst b/Documentation/networking/tc-queue-filters.rst
new file mode 100644
index 000000000000..6b417092276f
--- /dev/null
+++ b/Documentation/networking/tc-queue-filters.rst
@@ -0,0 +1,37 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=========================
+TC queue based filtering
+=========================
+
+TC can be used for directing traffic to either a set of queues or
+to a single queue on both the transmit and receive side.
+
+On the transmit side:
+
+1) TC filter directing traffic to a set of queues is achieved
+   using the action skbedit priority for Tx priority selection,
+   the priority maps to a traffic class (set of queues) when
+   the queue-sets are configured using mqprio.
+
+2) TC filter directs traffic to a transmit queue with the action
+   skbedit queue_mapping $tx_qid. The action skbedit queue_mapping
+   for transmit queue is executed in software only and cannot be
+   offloaded.
+
+Likewise, on the receive side, the two filters for selecting set of
+queues and/or a single queue are supported as below:
+
+1) TC flower filter directs incoming traffic to a set of queues using
+   the 'hw_tc' option.
+   hw_tc $TCID - Specify a hardware traffic class to pass matching
+   packets on to. TCID is in the range 0 through 15.
+
+2) TC filter with action skbedit queue_mapping $rx_qid selects a
+   receive queue. The action skbedit queue_mapping for receive queue
+   is supported only in hardware. Multiple filters may compete in
+   the hardware for queue selection. In such case, the hardware
+   pipeline resolves conflicts based on priority. On Intel E810
+   devices, TC filter directing traffic to a queue have higher
+   priority over flow director filter assigning a queue. The hash
+   filter has lowest priority.


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [net-next PATCH v3 0/3] Extend action skbedit to RX queue mapping
  2022-10-21  7:58 [net-next PATCH v3 0/3] Extend action skbedit to RX queue mapping Amritha Nambiar
                   ` (2 preceding siblings ...)
  2022-10-21  7:58 ` [net-next PATCH v3 3/3] Documentation: networking: TC queue based filtering Amritha Nambiar
@ 2022-10-25  9:00 ` patchwork-bot+netdevbpf
  3 siblings, 0 replies; 11+ messages in thread
From: patchwork-bot+netdevbpf @ 2022-10-25  9:00 UTC (permalink / raw)
  To: Amritha Nambiar
  Cc: netdev, kuba, alexander.duyck, jhs, jiri, xiyou.wangcong,
	vinicius.gomes, sridhar.samudrala

Hello:

This series was applied to netdev/net-next.git (master)
by Paolo Abeni <pabeni@redhat.com>:

On Fri, 21 Oct 2022 00:58:34 -0700 you wrote:
> Based on the discussion on
> https://lore.kernel.org/netdev/166260012413.81018.8010396115034847972.stgit@anambiarhost.jf.intel.com/ ,
> the following series extends skbedit tc action to RX queue mapping.
> Currently, skbedit action in tc allows overriding of transmit queue.
> Extending this ability of skedit action supports the selection of
> receive queue for incoming packets. On the receive side, this action
> is supported only in hardware, so the skip_sw flag is enforced.
> 
> [...]

Here is the summary with links:
  - [net-next,v3,1/3] act_skbedit: skbedit queue mapping for receive queue
    https://git.kernel.org/netdev/net-next/c/4a6a676f8c16
  - [net-next,v3,2/3] ice: Enable RX queue selection using skbedit action
    https://git.kernel.org/netdev/net-next/c/143b86f346c7
  - [net-next,v3,3/3] Documentation: networking: TC queue based filtering
    https://git.kernel.org/netdev/net-next/c/d5ae8ecf3832

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [net-next PATCH v3 1/3] act_skbedit: skbedit queue mapping for receive queue
  2022-10-21  7:58 ` [net-next PATCH v3 1/3] act_skbedit: skbedit queue mapping for receive queue Amritha Nambiar
@ 2022-10-26 11:40   ` Roi Dayan
  2022-10-26 16:17     ` Jakub Kicinski
  0 siblings, 1 reply; 11+ messages in thread
From: Roi Dayan @ 2022-10-26 11:40 UTC (permalink / raw)
  To: Amritha Nambiar, netdev, kuba
  Cc: alexander.duyck, jhs, jiri, xiyou.wangcong, vinicius.gomes,
	sridhar.samudrala, Maor Dickman, Tariq Toukan, Saeed Mahameed,
	Leon Romanovsky, Pablo Neira Ayuso


>  
>  /* Update lastuse only if needed, to avoid dirtying a cache line.
>   * We use a temp variable to avoid fetching jiffies twice.
> diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h
> index e343f9f8363e..7a60bc6d72c9 100644
> --- a/include/net/flow_offload.h
> +++ b/include/net/flow_offload.h
> @@ -155,6 +155,7 @@ enum flow_action_id {
>  	FLOW_ACTION_MARK,
>  	FLOW_ACTION_PTYPE,
>  	FLOW_ACTION_PRIORITY,
> +	FLOW_ACTION_RX_QUEUE_MAPPING,
>  	FLOW_ACTION_WAKE,
>  	FLOW_ACTION_QUEUE,
>  	FLOW_ACTION_SAMPLE,
> @@ -247,6 +248,7 @@ struct flow_action_entry {
>  		u32			csum_flags;	/* FLOW_ACTION_CSUM */
>  		u32			mark;		/* FLOW_ACTION_MARK */
>  		u16                     ptype;          /* FLOW_ACTION_PTYPE */
> +		u16			rx_queue;	/* FLOW_ACTION_RX_QUEUE_MAPPING */
>  		u32			priority;	/* FLOW_ACTION_PRIORITY */
>  		struct {				/* FLOW_ACTION_QUEUE */
>  			u32		ctx;


Hi,

This patch broke mlx5_core TC offloads.
We have a generic code part going over the enum values and have a list
of action pointers to handle parsing each action without knowing the action.
The list of actions depends on being aligned with the values order of
the enum which I think usually new values should go to the end of the list.
I'm not sure if other code parts are broken from this change but at
least one part is.
New values were always inserted at the end.

Can you make a fixup patch to move FLOW_ACTION_RX_QUEUE_MAPPING to
the end of the enum list?
i.e. right before NUM_FLOW_ACTIONS.

Thanks,
Roi

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [net-next PATCH v3 1/3] act_skbedit: skbedit queue mapping for receive queue
  2022-10-26 11:40   ` Roi Dayan
@ 2022-10-26 16:17     ` Jakub Kicinski
  2022-10-27  7:12       ` Roi Dayan
  0 siblings, 1 reply; 11+ messages in thread
From: Jakub Kicinski @ 2022-10-26 16:17 UTC (permalink / raw)
  To: Roi Dayan
  Cc: Amritha Nambiar, netdev, alexander.duyck, jhs, jiri,
	xiyou.wangcong, vinicius.gomes, sridhar.samudrala, Maor Dickman,
	Tariq Toukan, Saeed Mahameed, Leon Romanovsky, Pablo Neira Ayuso

On Wed, 26 Oct 2022 14:40:39 +0300 Roi Dayan wrote:
> This patch broke mlx5_core TC offloads.
> We have a generic code part going over the enum values and have a list
> of action pointers to handle parsing each action without knowing the action.
> The list of actions depends on being aligned with the values order of
> the enum which I think usually new values should go to the end of the list.
> I'm not sure if other code parts are broken from this change but at
> least one part is.
> New values were always inserted at the end.
> 
> Can you make a fixup patch to move FLOW_ACTION_RX_QUEUE_MAPPING to
> the end of the enum list?
> i.e. right before NUM_FLOW_ACTIONS.

Odd, can you point us to the exact code that got broken?
There are no guarantees on ordering of kernel-internal enum
and I think it's a bad idea to make such precedent.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [net-next PATCH v3 1/3] act_skbedit: skbedit queue mapping for receive queue
  2022-10-26 16:17     ` Jakub Kicinski
@ 2022-10-27  7:12       ` Roi Dayan
  2022-10-27  8:10         ` Roi Dayan
  2022-10-27  8:10         ` Saeed Mahameed
  0 siblings, 2 replies; 11+ messages in thread
From: Roi Dayan @ 2022-10-27  7:12 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Amritha Nambiar, netdev, alexander.duyck, jhs, jiri,
	xiyou.wangcong, vinicius.gomes, sridhar.samudrala, Maor Dickman,
	Tariq Toukan, Saeed Mahameed, Leon Romanovsky, Pablo Neira Ayuso



On 26/10/2022 19:17, Jakub Kicinski wrote:
> On Wed, 26 Oct 2022 14:40:39 +0300 Roi Dayan wrote:
>> This patch broke mlx5_core TC offloads.
>> We have a generic code part going over the enum values and have a list
>> of action pointers to handle parsing each action without knowing the action.
>> The list of actions depends on being aligned with the values order of
>> the enum which I think usually new values should go to the end of the list.
>> I'm not sure if other code parts are broken from this change but at
>> least one part is.
>> New values were always inserted at the end.
>>
>> Can you make a fixup patch to move FLOW_ACTION_RX_QUEUE_MAPPING to
>> the end of the enum list?
>> i.e. right before NUM_FLOW_ACTIONS.
> 
> Odd, can you point us to the exact code that got broken?
> There are no guarantees on ordering of kernel-internal enum
> and I think it's a bad idea to make such precedent.


ok. I were in the thought order is kept.

You can see our usage in drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
in function parse_tc_actions().
we loop over the actions and get a struct with function pointers
that represent the flow action and we use those function pointers
to parse whats needed without parse_tc_actions() knowing the action.

the function pointers are in drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/act.c
see static struct mlx5e_tc_act *tc_acts_fdb[NUM_FLOW_ACTIONS].
each function handling code is in a different file under that sub folder.

if order is not important i guess i'll do a function to return the ops i need
per enum value.
please let me know if to continue this road.
thanks

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [net-next PATCH v3 1/3] act_skbedit: skbedit queue mapping for receive queue
  2022-10-27  7:12       ` Roi Dayan
@ 2022-10-27  8:10         ` Roi Dayan
  2022-10-28  2:48           ` Jakub Kicinski
  2022-10-27  8:10         ` Saeed Mahameed
  1 sibling, 1 reply; 11+ messages in thread
From: Roi Dayan @ 2022-10-27  8:10 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Amritha Nambiar, netdev, alexander.duyck, jhs, jiri,
	xiyou.wangcong, vinicius.gomes, sridhar.samudrala, Maor Dickman,
	Tariq Toukan, Saeed Mahameed, Leon Romanovsky, Pablo Neira Ayuso



On 27/10/2022 10:12, Roi Dayan wrote:
> 
> 
> On 26/10/2022 19:17, Jakub Kicinski wrote:
>> On Wed, 26 Oct 2022 14:40:39 +0300 Roi Dayan wrote:
>>> This patch broke mlx5_core TC offloads.
>>> We have a generic code part going over the enum values and have a list
>>> of action pointers to handle parsing each action without knowing the action.
>>> The list of actions depends on being aligned with the values order of
>>> the enum which I think usually new values should go to the end of the list.
>>> I'm not sure if other code parts are broken from this change but at
>>> least one part is.
>>> New values were always inserted at the end.
>>>
>>> Can you make a fixup patch to move FLOW_ACTION_RX_QUEUE_MAPPING to
>>> the end of the enum list?
>>> i.e. right before NUM_FLOW_ACTIONS.
>>
>> Odd, can you point us to the exact code that got broken?
>> There are no guarantees on ordering of kernel-internal enum
>> and I think it's a bad idea to make such precedent.
> 
> 
> ok. I were in the thought order is kept.
> 
> You can see our usage in drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
> in function parse_tc_actions().
> we loop over the actions and get a struct with function pointers
> that represent the flow action and we use those function pointers
> to parse whats needed without parse_tc_actions() knowing the action.
> 
> the function pointers are in drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/act.c
> see static struct mlx5e_tc_act *tc_acts_fdb[NUM_FLOW_ACTIONS].
> each function handling code is in a different file under that sub folder.
> 
> if order is not important i guess i'll do a function to return the ops i need
> per enum value.
> please let me know if to continue this road.
> thanks

Hi,

going to do this change, which I didn't remember to do from the start.

static struct mlx5e_tc_act *tc_acts_fdb[NUM_FLOW_ACTIONS] = {                                       
        [FLOW_ACTION_ACCEPT] = &mlx5e_tc_act_accept,                                                
        [FLOW_ACTION_DROP] = &mlx5e_tc_act_drop,                                                    
        [FLOW_ACTION_TRAP] = &mlx5e_tc_act_trap,                                                    
        [FLOW_ACTION_GOTO] = &mlx5e_tc_act_goto,                 
.
.
.


then the ordering is not important.

Thanks,
Roi

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [net-next PATCH v3 1/3] act_skbedit: skbedit queue mapping for receive queue
  2022-10-27  7:12       ` Roi Dayan
  2022-10-27  8:10         ` Roi Dayan
@ 2022-10-27  8:10         ` Saeed Mahameed
  1 sibling, 0 replies; 11+ messages in thread
From: Saeed Mahameed @ 2022-10-27  8:10 UTC (permalink / raw)
  To: Roi Dayan
  Cc: Jakub Kicinski, Amritha Nambiar, netdev, alexander.duyck, jhs,
	jiri, xiyou.wangcong, vinicius.gomes, sridhar.samudrala,
	Maor Dickman, Tariq Toukan, Saeed Mahameed, Leon Romanovsky,
	Pablo Neira Ayuso

On 27 Oct 10:12, Roi Dayan wrote:
>
>
>On 26/10/2022 19:17, Jakub Kicinski wrote:
>> On Wed, 26 Oct 2022 14:40:39 +0300 Roi Dayan wrote:
>>> This patch broke mlx5_core TC offloads.
>>> We have a generic code part going over the enum values and have a list
>>> of action pointers to handle parsing each action without knowing the action.
>>> The list of actions depends on being aligned with the values order of
>>> the enum which I think usually new values should go to the end of the list.
>>> I'm not sure if other code parts are broken from this change but at
>>> least one part is.
>>> New values were always inserted at the end.
>>>
>>> Can you make a fixup patch to move FLOW_ACTION_RX_QUEUE_MAPPING to
>>> the end of the enum list?
>>> i.e. right before NUM_FLOW_ACTIONS.
>>
>> Odd, can you point us to the exact code that got broken?
>> There are no guarantees on ordering of kernel-internal enum
>> and I think it's a bad idea to make such precedent.
>
>
>ok. I were in the thought order is kept.
>
>You can see our usage in drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
>in function parse_tc_actions().
>we loop over the actions and get a struct with function pointers
>that represent the flow action and we use those function pointers
>to parse whats needed without parse_tc_actions() knowing the action.
>
>the function pointers are in drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/act.c
>see static struct mlx5e_tc_act *tc_acts_fdb[NUM_FLOW_ACTIONS].
>each function handling code is in a different file under that sub folder.
>
>if order is not important i guess i'll do a function to return the ops i need
>per enum value.
>please let me know if to continue this road.
>thanks

Order is not guaranteed, let's have a robust solution.
You can define an explicit static mapping in the driver, not in a for loop.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [net-next PATCH v3 1/3] act_skbedit: skbedit queue mapping for receive queue
  2022-10-27  8:10         ` Roi Dayan
@ 2022-10-28  2:48           ` Jakub Kicinski
  0 siblings, 0 replies; 11+ messages in thread
From: Jakub Kicinski @ 2022-10-28  2:48 UTC (permalink / raw)
  To: Roi Dayan
  Cc: Amritha Nambiar, netdev, alexander.duyck, jhs, jiri,
	xiyou.wangcong, vinicius.gomes, sridhar.samudrala, Maor Dickman,
	Tariq Toukan, Saeed Mahameed, Leon Romanovsky, Pablo Neira Ayuso

On Thu, 27 Oct 2022 11:10:21 +0300 Roi Dayan wrote:
> going to do this change, which I didn't remember to do from the start.
> 
> static struct mlx5e_tc_act *tc_acts_fdb[NUM_FLOW_ACTIONS] = {
>         [FLOW_ACTION_ACCEPT] = &mlx5e_tc_act_accept,
>         [FLOW_ACTION_DROP] = &mlx5e_tc_act_drop,
>         [FLOW_ACTION_TRAP] = &mlx5e_tc_act_trap,
>         [FLOW_ACTION_GOTO] = &mlx5e_tc_act_goto, 

👍

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2022-10-28  2:48 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-21  7:58 [net-next PATCH v3 0/3] Extend action skbedit to RX queue mapping Amritha Nambiar
2022-10-21  7:58 ` [net-next PATCH v3 1/3] act_skbedit: skbedit queue mapping for receive queue Amritha Nambiar
2022-10-26 11:40   ` Roi Dayan
2022-10-26 16:17     ` Jakub Kicinski
2022-10-27  7:12       ` Roi Dayan
2022-10-27  8:10         ` Roi Dayan
2022-10-28  2:48           ` Jakub Kicinski
2022-10-27  8:10         ` Saeed Mahameed
2022-10-21  7:58 ` [net-next PATCH v3 2/3] ice: Enable RX queue selection using skbedit action Amritha Nambiar
2022-10-21  7:58 ` [net-next PATCH v3 3/3] Documentation: networking: TC queue based filtering Amritha Nambiar
2022-10-25  9:00 ` [net-next PATCH v3 0/3] Extend action skbedit to RX queue mapping patchwork-bot+netdevbpf

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.