Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

octeontx2-pf: Add ucast filter count configurability via devlink.

The existing method of reserving unicast filter count leads to wasted
MCAM entries if the functionality is not used or fewer entries are used.
Furthermore, the amount of MCAM entries differs amongst Octeon SoCs.
We implemented a means to adjust the UC filter count via devlink,
allowing for better use of MCAM entries across Netdev apps.

commands:

To get the current unicast filter count
# devlink dev param show pci/0002:02:00.0 name unicast_filter_count

To change/set the unicast filter count
# devlink dev param set pci/0002:02:00.0 name unicast_filter_count
value 5 cmode runtime

Signed-off-by: Sai Krishna <saikrishnag@marvell.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Sai Krishna and committed by
David S. Miller
39c46918 4558645d

+95 -14
+16
Documentation/networking/devlink/octeontx2.rst
··· 40 40 - runtime 41 41 - Use to set the quantum which hardware uses for scheduling among transmit queues. 42 42 Hardware uses weighted DWRR algorithm to schedule among all transmit queues. 43 + 44 + The ``octeontx2 PF`` driver implements the following driver-specific parameters. 45 + 46 + .. list-table:: Driver-specific parameters implemented 47 + :widths: 5 5 5 85 48 + 49 + * - Name 50 + - Type 51 + - Mode 52 + - Description 53 + * - ``unicast_filter_count`` 54 + - u8 55 + - runtime 56 + - Set the maximum number of unicast filters that can be programmed for 57 + the device. This can be used to achieve better device resource 58 + utilization, avoiding over consumption of unused MCAM table entries.
+3 -4
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
··· 346 346 u16 *def_ent; 347 347 u16 nr_flows; 348 348 #define OTX2_DEFAULT_FLOWCOUNT 16 349 - #define OTX2_MAX_UNICAST_FLOWS 8 349 + #define OTX2_DEFAULT_UNICAST_FLOWS 4 350 350 #define OTX2_MAX_VLAN_FLOWS 1 351 351 #define OTX2_MAX_TC_FLOWS OTX2_DEFAULT_FLOWCOUNT 352 - #define OTX2_MCAM_COUNT (OTX2_DEFAULT_FLOWCOUNT + \ 353 - OTX2_MAX_UNICAST_FLOWS + \ 354 - OTX2_MAX_VLAN_FLOWS) 355 352 u16 unicast_offset; 356 353 u16 rx_vlan_offset; 357 354 u16 vf_vlan_offset; ··· 362 365 u16 max_flows; 363 366 refcount_t mark_flows; 364 367 struct list_head flow_list_tc; 368 + u8 ucast_flt_cnt; 365 369 bool ntuple; 366 370 }; 367 371 ··· 1065 1067 int otx2_smq_flush(struct otx2_nic *pfvf, int smq); 1066 1068 void otx2_free_bufs(struct otx2_nic *pfvf, struct otx2_pool *pool, 1067 1069 u64 iova, int size); 1070 + int otx2_mcam_entry_init(struct otx2_nic *pfvf); 1068 1071 1069 1072 /* tc support */ 1070 1073 int otx2_init_tc(struct otx2_nic *nic);
+64
drivers/net/ethernet/marvell/octeontx2/nic/otx2_devlink.c
··· 64 64 return 0; 65 65 } 66 66 67 + static int otx2_dl_ucast_flt_cnt_set(struct devlink *devlink, u32 id, 68 + struct devlink_param_gset_ctx *ctx, 69 + struct netlink_ext_ack *extack) 70 + { 71 + struct otx2_devlink *otx2_dl = devlink_priv(devlink); 72 + struct otx2_nic *pfvf = otx2_dl->pfvf; 73 + int err; 74 + 75 + pfvf->flow_cfg->ucast_flt_cnt = ctx->val.vu8; 76 + 77 + otx2_mcam_flow_del(pfvf); 78 + err = otx2_mcam_entry_init(pfvf); 79 + if (err) 80 + return err; 81 + 82 + return 0; 83 + } 84 + 85 + static int otx2_dl_ucast_flt_cnt_get(struct devlink *devlink, u32 id, 86 + struct devlink_param_gset_ctx *ctx) 87 + { 88 + struct otx2_devlink *otx2_dl = devlink_priv(devlink); 89 + struct otx2_nic *pfvf = otx2_dl->pfvf; 90 + 91 + ctx->val.vu8 = pfvf->flow_cfg ? pfvf->flow_cfg->ucast_flt_cnt : 0; 92 + 93 + return 0; 94 + } 95 + 96 + static int otx2_dl_ucast_flt_cnt_validate(struct devlink *devlink, u32 id, 97 + union devlink_param_value val, 98 + struct netlink_ext_ack *extack) 99 + { 100 + struct otx2_devlink *otx2_dl = devlink_priv(devlink); 101 + struct otx2_nic *pfvf = otx2_dl->pfvf; 102 + 103 + /* Check for UNICAST filter support*/ 104 + if (!(pfvf->flags & OTX2_FLAG_UCAST_FLTR_SUPPORT)) { 105 + NL_SET_ERR_MSG_MOD(extack, 106 + "Unicast filter not enabled"); 107 + return -EINVAL; 108 + } 109 + 110 + if (!pfvf->flow_cfg) { 111 + NL_SET_ERR_MSG_MOD(extack, 112 + "pfvf->flow_cfg not initialized"); 113 + return -EINVAL; 114 + } 115 + 116 + if (pfvf->flow_cfg->nr_flows) { 117 + NL_SET_ERR_MSG_MOD(extack, 118 + "Cannot modify count when there are active rules"); 119 + return -EINVAL; 120 + } 121 + 122 + return 0; 123 + } 124 + 67 125 enum otx2_dl_param_id { 68 126 OTX2_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX, 69 127 OTX2_DEVLINK_PARAM_ID_MCAM_COUNT, 128 + OTX2_DEVLINK_PARAM_ID_UCAST_FLT_CNT, 70 129 }; 71 130 72 131 static const struct devlink_param otx2_dl_params[] = { ··· 134 75 BIT(DEVLINK_PARAM_CMODE_RUNTIME), 135 76 otx2_dl_mcam_count_get, otx2_dl_mcam_count_set, 136 77 otx2_dl_mcam_count_validate), 78 + DEVLINK_PARAM_DRIVER(OTX2_DEVLINK_PARAM_ID_UCAST_FLT_CNT, 79 + "unicast_filter_count", DEVLINK_PARAM_TYPE_U8, 80 + BIT(DEVLINK_PARAM_CMODE_RUNTIME), 81 + otx2_dl_ucast_flt_cnt_get, otx2_dl_ucast_flt_cnt_set, 82 + otx2_dl_ucast_flt_cnt_validate), 137 83 }; 138 84 139 85 static const struct devlink_ops otx2_devlink_ops = {
+11 -9
drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c
··· 12 12 13 13 #define OTX2_DEFAULT_ACTION 0x1 14 14 15 - static int otx2_mcam_entry_init(struct otx2_nic *pfvf); 16 - 17 15 struct otx2_flow { 18 16 struct ethtool_rx_flow_spec flow_spec; 19 17 struct list_head list; ··· 159 161 } 160 162 EXPORT_SYMBOL(otx2_alloc_mcam_entries); 161 163 162 - static int otx2_mcam_entry_init(struct otx2_nic *pfvf) 164 + int otx2_mcam_entry_init(struct otx2_nic *pfvf) 163 165 { 164 166 struct otx2_flow_config *flow_cfg = pfvf->flow_cfg; 165 167 struct npc_get_field_status_req *freq; ··· 170 172 int ent, count; 171 173 172 174 vf_vlan_max_flows = pfvf->total_vfs * OTX2_PER_VF_VLAN_FLOWS; 173 - count = OTX2_MAX_UNICAST_FLOWS + 175 + count = flow_cfg->ucast_flt_cnt + 174 176 OTX2_MAX_VLAN_FLOWS + vf_vlan_max_flows; 175 177 176 178 flow_cfg->def_ent = devm_kmalloc_array(pfvf->dev, count, ··· 212 214 flow_cfg->vf_vlan_offset = 0; 213 215 flow_cfg->unicast_offset = vf_vlan_max_flows; 214 216 flow_cfg->rx_vlan_offset = flow_cfg->unicast_offset + 215 - OTX2_MAX_UNICAST_FLOWS; 217 + flow_cfg->ucast_flt_cnt; 216 218 pfvf->flags |= OTX2_FLAG_UCAST_FLTR_SUPPORT; 217 219 218 220 /* Check if NPC_DMAC field is supported ··· 253 255 refcount_set(&flow_cfg->mark_flows, 1); 254 256 return 0; 255 257 } 258 + EXPORT_SYMBOL(otx2_mcam_entry_init); 256 259 257 260 /* TODO : revisit on size */ 258 261 #define OTX2_DMAC_FLTR_BITMAP_SZ (4 * 2048 + 32) ··· 301 302 INIT_LIST_HEAD(&pf->flow_cfg->flow_list); 302 303 INIT_LIST_HEAD(&pf->flow_cfg->flow_list_tc); 303 304 305 + pf->flow_cfg->ucast_flt_cnt = OTX2_DEFAULT_UNICAST_FLOWS; 306 + 304 307 /* Allocate bare minimum number of MCAM entries needed for 305 308 * unicast and ntuple filters. 306 309 */ ··· 315 314 return 0; 316 315 317 316 pf->mac_table = devm_kzalloc(pf->dev, sizeof(struct otx2_mac_table) 318 - * OTX2_MAX_UNICAST_FLOWS, GFP_KERNEL); 317 + * pf->flow_cfg->ucast_flt_cnt, GFP_KERNEL); 319 318 if (!pf->mac_table) 320 319 return -ENOMEM; 321 320 ··· 357 356 return -ENOMEM; 358 357 359 358 /* dont have free mcam entries or uc list is greater than alloted */ 360 - if (netdev_uc_count(pf->netdev) > OTX2_MAX_UNICAST_FLOWS) 359 + if (netdev_uc_count(pf->netdev) > pf->flow_cfg->ucast_flt_cnt) 361 360 return -ENOMEM; 362 361 363 362 mutex_lock(&pf->mbox.lock); ··· 368 367 } 369 368 370 369 /* unicast offset starts with 32 0..31 for ntuple */ 371 - for (i = 0; i < OTX2_MAX_UNICAST_FLOWS; i++) { 370 + for (i = 0; i < pf->flow_cfg->ucast_flt_cnt; i++) { 372 371 if (pf->mac_table[i].inuse) 373 372 continue; 374 373 ether_addr_copy(pf->mac_table[i].addr, mac); ··· 411 410 { 412 411 int i; 413 412 414 - for (i = 0; i < OTX2_MAX_UNICAST_FLOWS; i++) { 413 + for (i = 0; i < pf->flow_cfg->ucast_flt_cnt; i++) { 415 414 if (!pf->mac_table[i].inuse) 416 415 continue; 417 416 ··· 1395 1394 } 1396 1395 1397 1396 pfvf->flags &= ~OTX2_FLAG_MCAM_ENTRIES_ALLOC; 1397 + flow_cfg->max_flows = 0; 1398 1398 mutex_unlock(&pfvf->mbox.lock); 1399 1399 1400 1400 return 0;
+1 -1
drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
··· 1714 1714 return; 1715 1715 1716 1716 if ((netdev->flags & IFF_PROMISC) || 1717 - (netdev_uc_count(netdev) > OTX2_MAX_UNICAST_FLOWS)) { 1717 + (netdev_uc_count(netdev) > pf->flow_cfg->ucast_flt_cnt)) { 1718 1718 promisc = true; 1719 1719 } 1720 1720