Chenmin Sun | 9b8121c | 2021-01-11 20:03:13 +0800 | [diff] [blame] | 1 | From a304784408adfaab3918d8578264c48004d4e81e Mon Sep 17 00:00:00 2001 |
| 2 | From: Beilei Xing <beilei.xing@intel.com> |
| 3 | Date: Tue, 5 Jan 2021 11:12:56 +0800 |
| 4 | Subject: [FDIO] net/i40e: fix flex payload rule conflict |
| 5 | |
| 6 | With the following commands, the second flow can't |
| 7 | be created successfully. |
| 8 | |
| 9 | 1. flow create 0 ingress pattern eth / ipv4 / udp / |
| 10 | raw relative is 1 pattern is 0102030405 / end |
| 11 | actions drop / end |
| 12 | 2. flow destroy 0 rule 0 |
| 13 | 3. flow create 0 ingress pattern eth / ipv4 / udp / |
| 14 | raw relative is 1 pattern is 010203040506 / end |
| 15 | actions drop / end |
| 16 | |
| 17 | The root cause is that a flag for flex pit isn't reset. |
| 18 | |
| 19 | Fixes: 6ced3dd72f5f ("net/i40e: support flexible payload parsing for FDIR") |
| 20 | Cc: stable@dpdk.org |
| 21 | |
| 22 | Reported-by: Chenmin Sun <chenmin.sun@intel.com> |
| 23 | Signed-off-by: Beilei Xing <beilei.xing@intel.com> |
| 24 | Acked-by: Jeff Guo <jia.guo@intel.com> |
| 25 | --- |
| 26 | drivers/net/i40e/i40e_ethdev.h | 3 +++ |
| 27 | drivers/net/i40e/i40e_fdir.c | 19 ++++++++++++++++--- |
| 28 | drivers/net/i40e/i40e_flow.c | 4 ++++ |
| 29 | 3 files changed, 23 insertions(+), 3 deletions(-) |
| 30 | |
| 31 | diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h |
| 32 | index 696c5aaf7..aac226999 100644 |
| 33 | --- a/drivers/net/i40e/i40e_ethdev.h |
| 34 | +++ b/drivers/net/i40e/i40e_ethdev.h |
| 35 | @@ -636,6 +636,7 @@ struct i40e_fdir_flow_ext { |
| 36 | bool is_udp; /* ipv4|ipv6 udp flow */ |
| 37 | enum i40e_flxpld_layer_idx layer_idx; |
| 38 | struct i40e_fdir_flex_pit flex_pit[I40E_MAX_FLXPLD_LAYER * I40E_MAX_FLXPLD_FIED]; |
| 39 | + bool is_flex_flow; |
| 40 | }; |
| 41 | |
| 42 | /* A structure used to define the input for a flow director filter entry */ |
| 43 | @@ -784,6 +785,8 @@ struct i40e_fdir_info { |
| 44 | bool flex_mask_flag[I40E_FILTER_PCTYPE_MAX]; |
| 45 | |
| 46 | bool inset_flag[I40E_FILTER_PCTYPE_MAX]; /* Mark if input set is set */ |
| 47 | + |
| 48 | + uint32_t flex_flow_count[I40E_MAX_FLXPLD_LAYER]; |
| 49 | }; |
| 50 | |
| 51 | /* Ethertype filter number HW supports */ |
| 52 | diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c |
| 53 | index 50c0eee9f..0343e8b09 100644 |
| 54 | --- a/drivers/net/i40e/i40e_fdir.c |
| 55 | +++ b/drivers/net/i40e/i40e_fdir.c |
| 56 | @@ -355,6 +355,7 @@ i40e_init_flx_pld(struct i40e_pf *pf) |
| 57 | I40E_PRTQF_FLX_PIT(index + 1), 0x0000FC29);/*non-used*/ |
| 58 | I40E_WRITE_REG(hw, |
| 59 | I40E_PRTQF_FLX_PIT(index + 2), 0x0000FC2A);/*non-used*/ |
| 60 | + pf->fdir.flex_pit_flag[i] = 0; |
| 61 | } |
| 62 | |
| 63 | /* initialize the masks */ |
| 64 | @@ -1513,8 +1514,6 @@ i40e_flow_set_fdir_flex_pit(struct i40e_pf *pf, |
| 65 | I40E_WRITE_REG(hw, I40E_PRTQF_FLX_PIT(field_idx), flx_pit); |
| 66 | min_next_off++; |
| 67 | } |
| 68 | - |
| 69 | - pf->fdir.flex_pit_flag[layer_idx] = 1; |
| 70 | } |
| 71 | |
| 72 | static int |
| 73 | @@ -1686,7 +1685,7 @@ i40e_flow_add_del_fdir_filter(struct rte_eth_dev *dev, |
| 74 | i40e_fdir_filter_convert(filter, &check_filter); |
| 75 | |
| 76 | if (add) { |
| 77 | - if (!filter->input.flow_ext.customized_pctype) { |
| 78 | + if (filter->input.flow_ext.is_flex_flow) { |
| 79 | for (i = 0; i < filter->input.flow_ext.raw_id; i++) { |
| 80 | layer_idx = filter->input.flow_ext.layer_idx; |
| 81 | field_idx = layer_idx * I40E_MAX_FLXPLD_FIED + i; |
| 82 | @@ -1738,6 +1737,9 @@ i40e_flow_add_del_fdir_filter(struct rte_eth_dev *dev, |
| 83 | fdir_info->fdir_guarantee_free_space > 0) |
| 84 | wait_status = false; |
| 85 | } else { |
| 86 | + if (filter->input.flow_ext.is_flex_flow) |
| 87 | + layer_idx = filter->input.flow_ext.layer_idx; |
| 88 | + |
| 89 | node = i40e_sw_fdir_filter_lookup(fdir_info, |
| 90 | &check_filter.fdir.input); |
| 91 | if (!node) { |
| 92 | @@ -1785,6 +1787,17 @@ i40e_flow_add_del_fdir_filter(struct rte_eth_dev *dev, |
| 93 | goto error_op; |
| 94 | } |
| 95 | |
| 96 | + if (filter->input.flow_ext.is_flex_flow) { |
| 97 | + if (add) { |
| 98 | + fdir_info->flex_flow_count[layer_idx]++; |
| 99 | + pf->fdir.flex_pit_flag[layer_idx] = 1; |
| 100 | + } else { |
| 101 | + fdir_info->flex_flow_count[layer_idx]--; |
| 102 | + if (!fdir_info->flex_flow_count[layer_idx]) |
| 103 | + pf->fdir.flex_pit_flag[layer_idx] = 0; |
| 104 | + } |
| 105 | + } |
| 106 | + |
| 107 | if (add) { |
| 108 | fdir_info->fdir_actual_cnt++; |
| 109 | if (fdir_info->fdir_invalprio == 1 && |
| 110 | diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c |
| 111 | index b09ff6590..bbd666b7a 100644 |
| 112 | --- a/drivers/net/i40e/i40e_flow.c |
| 113 | +++ b/drivers/net/i40e/i40e_flow.c |
| 114 | @@ -3069,6 +3069,7 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, |
| 115 | &flex_pit, sizeof(struct i40e_fdir_flex_pit)); |
| 116 | filter->input.flow_ext.layer_idx = layer_idx; |
| 117 | filter->input.flow_ext.raw_id = raw_id; |
| 118 | + filter->input.flow_ext.is_flex_flow = true; |
| 119 | break; |
| 120 | case RTE_FLOW_ITEM_TYPE_VF: |
| 121 | vf_spec = item->spec; |
| 122 | @@ -5515,6 +5516,9 @@ i40e_flow_flush_fdir_filter(struct i40e_pf *pf) |
| 123 | pf->fdir.flex_mask_flag[pctype] = 0; |
| 124 | } |
| 125 | |
| 126 | + for (i = 0; i < I40E_MAX_FLXPLD_LAYER; i++) |
| 127 | + pf->fdir.flex_pit_flag[i] = 0; |
| 128 | + |
| 129 | /* Disable FDIR processing as all FDIR rules are now flushed */ |
| 130 | i40e_fdir_rx_proc_enable(dev, 0); |
| 131 | } |
| 132 | -- |
| 133 | 2.17.1 |
| 134 | |