Skip to content

Commit c7b7b48

Browse files
Yuval Mintzdavem330
authored andcommitted
bnx2x: Don't flush multicast MACs
When ndo_set_rx_mode() is called for bnx2x, as part of process of configuring the new MAC address filters [both unicast & multicast] driver begins by flushing the existing configuration and then iterating over the network device's list of addresses and configures those instead. This has the side-effect of creating a short gap where traffic wouldn't be properly classified, as no filters are configured in HW. While for unicasts this is rather insignificant [as unicast MACs don't frequently change while interface is actually running], for multicast traffic it does pose an issue as there are multicast-based networks where new multicast groups would constantly be removed and added. This patch tries to remedy this [at least for the newer adapters] - Instead of flushing & reconfiguring all existing multicast filters, the driver would instead create the approximate hash match that would result from the required filters. It would then compare it against the currently configured approximate hash match, and only add and remove the delta between those. Signed-off-by: Yuval Mintz <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 6546c78 commit c7b7b48

File tree

5 files changed

+241
-34
lines changed

5 files changed

+241
-34
lines changed

drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12560,8 +12560,10 @@ static int bnx2x_init_mcast_macs_list(struct bnx2x *bp,
1256012560
kcalloc(mc_count, sizeof(*mc_mac), GFP_ATOMIC);
1256112561
struct netdev_hw_addr *ha;
1256212562

12563-
if (!mc_mac)
12563+
if (!mc_mac) {
12564+
BNX2X_ERR("Failed to allocate mc MAC list\n");
1256412565
return -ENOMEM;
12566+
}
1256512567

1256612568
INIT_LIST_HEAD(&p->mcast_list);
1256712569

@@ -12632,7 +12634,7 @@ static int bnx2x_set_uc_list(struct bnx2x *bp)
1263212634
BNX2X_UC_LIST_MAC, &ramrod_flags);
1263312635
}
1263412636

12635-
static int bnx2x_set_mc_list(struct bnx2x *bp)
12637+
static int bnx2x_set_mc_list_e1x(struct bnx2x *bp)
1263612638
{
1263712639
struct net_device *dev = bp->dev;
1263812640
struct bnx2x_mcast_ramrod_params rparam = {NULL};
@@ -12650,11 +12652,8 @@ static int bnx2x_set_mc_list(struct bnx2x *bp)
1265012652
/* then, configure a new MACs list */
1265112653
if (netdev_mc_count(dev)) {
1265212654
rc = bnx2x_init_mcast_macs_list(bp, &rparam);
12653-
if (rc) {
12654-
BNX2X_ERR("Failed to create multicast MACs list: %d\n",
12655-
rc);
12655+
if (rc)
1265612656
return rc;
12657-
}
1265812657

1265912658
/* Now add the new MACs */
1266012659
rc = bnx2x_config_mcast(bp, &rparam,
@@ -12669,6 +12668,42 @@ static int bnx2x_set_mc_list(struct bnx2x *bp)
1266912668
return rc;
1267012669
}
1267112670

12671+
static int bnx2x_set_mc_list(struct bnx2x *bp)
12672+
{
12673+
struct bnx2x_mcast_ramrod_params rparam = {NULL};
12674+
struct net_device *dev = bp->dev;
12675+
int rc = 0;
12676+
12677+
/* On older adapters, we need to flush and re-add filters */
12678+
if (CHIP_IS_E1x(bp))
12679+
return bnx2x_set_mc_list_e1x(bp);
12680+
12681+
rparam.mcast_obj = &bp->mcast_obj;
12682+
12683+
if (netdev_mc_count(dev)) {
12684+
rc = bnx2x_init_mcast_macs_list(bp, &rparam);
12685+
if (rc)
12686+
return rc;
12687+
12688+
/* Override the curently configured set of mc filters */
12689+
rc = bnx2x_config_mcast(bp, &rparam,
12690+
BNX2X_MCAST_CMD_SET);
12691+
if (rc < 0)
12692+
BNX2X_ERR("Failed to set a new multicast configuration: %d\n",
12693+
rc);
12694+
12695+
bnx2x_free_mcast_macs_list(&rparam);
12696+
} else {
12697+
/* If no mc addresses are required, flush the configuration */
12698+
rc = bnx2x_config_mcast(bp, &rparam, BNX2X_MCAST_CMD_DEL);
12699+
if (rc)
12700+
BNX2X_ERR("Failed to clear multicast configuration %d\n",
12701+
rc);
12702+
}
12703+
12704+
return rc;
12705+
}
12706+
1267212707
/* If bp->state is OPEN, should be called with netif_addr_lock_bh() */
1267312708
static void bnx2x_set_rx_mode(struct net_device *dev)
1267412709
{

drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c

Lines changed: 180 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2600,6 +2600,12 @@ struct bnx2x_mcast_mac_elem {
26002600
u8 pad[2]; /* For a natural alignment of the following buffer */
26012601
};
26022602

2603+
struct bnx2x_mcast_bin_elem {
2604+
struct list_head link;
2605+
int bin;
2606+
int type; /* BNX2X_MCAST_CMD_SET_{ADD, DEL} */
2607+
};
2608+
26032609
struct bnx2x_pending_mcast_cmd {
26042610
struct list_head link;
26052611
int type; /* BNX2X_MCAST_CMD_X */
@@ -2609,6 +2615,11 @@ struct bnx2x_pending_mcast_cmd {
26092615
int next_bin; /* Needed for RESTORE flow with aprox match */
26102616
} data;
26112617

2618+
bool set_convert; /* in case type == BNX2X_MCAST_CMD_SET, this is set
2619+
* when macs_head had been converted to a list of
2620+
* bnx2x_mcast_bin_elem.
2621+
*/
2622+
26122623
bool done; /* set to true, when the command has been handled,
26132624
* practically used in 57712 handling only, where one pending
26142625
* command may be handled in a few operations. As long as for
@@ -2636,15 +2647,30 @@ static int bnx2x_mcast_enqueue_cmd(struct bnx2x *bp,
26362647
struct bnx2x_pending_mcast_cmd *new_cmd;
26372648
struct bnx2x_mcast_mac_elem *cur_mac = NULL;
26382649
struct bnx2x_mcast_list_elem *pos;
2639-
int macs_list_len = ((cmd == BNX2X_MCAST_CMD_ADD) ?
2640-
p->mcast_list_len : 0);
2650+
int macs_list_len = 0, macs_list_len_size;
2651+
2652+
/* When adding MACs we'll need to store their values */
2653+
if (cmd == BNX2X_MCAST_CMD_ADD || cmd == BNX2X_MCAST_CMD_SET)
2654+
macs_list_len = p->mcast_list_len;
26412655

26422656
/* If the command is empty ("handle pending commands only"), break */
26432657
if (!p->mcast_list_len)
26442658
return 0;
26452659

2646-
total_sz = sizeof(*new_cmd) +
2647-
macs_list_len * sizeof(struct bnx2x_mcast_mac_elem);
2660+
/* For a set command, we need to allocate sufficient memory for all
2661+
* the bins, since we can't analyze at this point how much memory would
2662+
* be required.
2663+
*/
2664+
macs_list_len_size = macs_list_len *
2665+
sizeof(struct bnx2x_mcast_mac_elem);
2666+
if (cmd == BNX2X_MCAST_CMD_SET) {
2667+
int bin_size = BNX2X_MCAST_BINS_NUM *
2668+
sizeof(struct bnx2x_mcast_bin_elem);
2669+
2670+
if (bin_size > macs_list_len_size)
2671+
macs_list_len_size = bin_size;
2672+
}
2673+
total_sz = sizeof(*new_cmd) + macs_list_len_size;
26482674

26492675
/* Add mcast is called under spin_lock, thus calling with GFP_ATOMIC */
26502676
new_cmd = kzalloc(total_sz, GFP_ATOMIC);
@@ -2662,6 +2688,7 @@ static int bnx2x_mcast_enqueue_cmd(struct bnx2x *bp,
26622688

26632689
switch (cmd) {
26642690
case BNX2X_MCAST_CMD_ADD:
2691+
case BNX2X_MCAST_CMD_SET:
26652692
cur_mac = (struct bnx2x_mcast_mac_elem *)
26662693
((u8 *)new_cmd + sizeof(*new_cmd));
26672694

@@ -2771,7 +2798,8 @@ static void bnx2x_mcast_set_one_rule_e2(struct bnx2x *bp,
27712798
u8 rx_tx_add_flag = bnx2x_mcast_get_rx_tx_flag(o);
27722799
int bin;
27732800

2774-
if ((cmd == BNX2X_MCAST_CMD_ADD) || (cmd == BNX2X_MCAST_CMD_RESTORE))
2801+
if ((cmd == BNX2X_MCAST_CMD_ADD) || (cmd == BNX2X_MCAST_CMD_RESTORE) ||
2802+
(cmd == BNX2X_MCAST_CMD_SET_ADD))
27752803
rx_tx_add_flag |= ETH_MULTICAST_RULES_CMD_IS_ADD;
27762804

27772805
data->rules[idx].cmd_general_data |= rx_tx_add_flag;
@@ -2797,6 +2825,16 @@ static void bnx2x_mcast_set_one_rule_e2(struct bnx2x *bp,
27972825
bin = cfg_data->bin;
27982826
break;
27992827

2828+
case BNX2X_MCAST_CMD_SET_ADD:
2829+
bin = cfg_data->bin;
2830+
BIT_VEC64_SET_BIT(o->registry.aprox_match.vec, bin);
2831+
break;
2832+
2833+
case BNX2X_MCAST_CMD_SET_DEL:
2834+
bin = cfg_data->bin;
2835+
BIT_VEC64_CLEAR_BIT(o->registry.aprox_match.vec, bin);
2836+
break;
2837+
28002838
default:
28012839
BNX2X_ERR("Unknown command: %d\n", cmd);
28022840
return;
@@ -2932,6 +2970,102 @@ static inline void bnx2x_mcast_hdl_pending_restore_e2(struct bnx2x *bp,
29322970
cmd_pos->data.next_bin++;
29332971
}
29342972

2973+
static void
2974+
bnx2x_mcast_hdl_pending_set_e2_convert(struct bnx2x *bp,
2975+
struct bnx2x_mcast_obj *o,
2976+
struct bnx2x_pending_mcast_cmd *cmd_pos)
2977+
{
2978+
u64 cur[BNX2X_MCAST_VEC_SZ], req[BNX2X_MCAST_VEC_SZ];
2979+
struct bnx2x_mcast_mac_elem *pmac_pos, *pmac_pos_n;
2980+
struct bnx2x_mcast_bin_elem *p_item;
2981+
int i, cnt = 0, mac_cnt = 0;
2982+
2983+
memset(req, 0, sizeof(u64) * BNX2X_MCAST_VEC_SZ);
2984+
memcpy(cur, o->registry.aprox_match.vec,
2985+
sizeof(u64) * BNX2X_MCAST_VEC_SZ);
2986+
2987+
/* Fill `current' with the required set of bins to configure */
2988+
list_for_each_entry_safe(pmac_pos, pmac_pos_n, &cmd_pos->data.macs_head,
2989+
link) {
2990+
int bin = bnx2x_mcast_bin_from_mac(pmac_pos->mac);
2991+
2992+
DP(BNX2X_MSG_SP, "Set contains %pM mcast MAC\n",
2993+
pmac_pos->mac);
2994+
2995+
BIT_VEC64_SET_BIT(req, bin);
2996+
list_del(&pmac_pos->link);
2997+
mac_cnt++;
2998+
}
2999+
3000+
/* We no longer have use for the MACs; Need to re-use memory for
3001+
* a list that will be used to configure bins.
3002+
*/
3003+
cmd_pos->set_convert = true;
3004+
p_item = (struct bnx2x_mcast_bin_elem *)(cmd_pos + 1);
3005+
INIT_LIST_HEAD(&cmd_pos->data.macs_head);
3006+
3007+
for (i = 0; i < BNX2X_MCAST_BINS_NUM; i++) {
3008+
bool b_current = !!BIT_VEC64_TEST_BIT(cur, i);
3009+
bool b_required = !!BIT_VEC64_TEST_BIT(req, i);
3010+
3011+
if (b_current == b_required)
3012+
continue;
3013+
3014+
p_item->bin = i;
3015+
p_item->type = b_required ? BNX2X_MCAST_CMD_SET_ADD
3016+
: BNX2X_MCAST_CMD_SET_DEL;
3017+
list_add_tail(&p_item->link , &cmd_pos->data.macs_head);
3018+
p_item++;
3019+
cnt++;
3020+
}
3021+
3022+
/* We now definitely know how many commands are hiding here.
3023+
* Also need to correct the disruption we've added to guarantee this
3024+
* would be enqueued.
3025+
*/
3026+
o->total_pending_num -= (o->max_cmd_len + mac_cnt);
3027+
o->total_pending_num += cnt;
3028+
3029+
DP(BNX2X_MSG_SP, "o->total_pending_num=%d\n", o->total_pending_num);
3030+
}
3031+
3032+
static void
3033+
bnx2x_mcast_hdl_pending_set_e2(struct bnx2x *bp,
3034+
struct bnx2x_mcast_obj *o,
3035+
struct bnx2x_pending_mcast_cmd *cmd_pos,
3036+
int *cnt)
3037+
{
3038+
union bnx2x_mcast_config_data cfg_data = {NULL};
3039+
struct bnx2x_mcast_bin_elem *p_item, *p_item_n;
3040+
3041+
/* This is actually a 2-part scheme - it starts by converting the MACs
3042+
* into a list of bins to be added/removed, and correcting the numbers
3043+
* on the object. this is now allowed, as we're now sure that all
3044+
* previous configured requests have already applied.
3045+
* The second part is actually adding rules for the newly introduced
3046+
* entries [like all the rest of the hdl_pending functions].
3047+
*/
3048+
if (!cmd_pos->set_convert)
3049+
bnx2x_mcast_hdl_pending_set_e2_convert(bp, o, cmd_pos);
3050+
3051+
list_for_each_entry_safe(p_item, p_item_n, &cmd_pos->data.macs_head,
3052+
link) {
3053+
cfg_data.bin = (u8)p_item->bin;
3054+
o->set_one_rule(bp, o, *cnt, &cfg_data, p_item->type);
3055+
(*cnt)++;
3056+
3057+
list_del(&p_item->link);
3058+
3059+
/* Break if we reached the maximum number of rules. */
3060+
if (*cnt >= o->max_cmd_len)
3061+
break;
3062+
}
3063+
3064+
/* if no more MACs to configure - we are done */
3065+
if (list_empty(&cmd_pos->data.macs_head))
3066+
cmd_pos->done = true;
3067+
}
3068+
29353069
static inline int bnx2x_mcast_handle_pending_cmds_e2(struct bnx2x *bp,
29363070
struct bnx2x_mcast_ramrod_params *p)
29373071
{
@@ -2955,6 +3089,10 @@ static inline int bnx2x_mcast_handle_pending_cmds_e2(struct bnx2x *bp,
29553089
&cnt);
29563090
break;
29573091

3092+
case BNX2X_MCAST_CMD_SET:
3093+
bnx2x_mcast_hdl_pending_set_e2(bp, o, cmd_pos, &cnt);
3094+
break;
3095+
29583096
default:
29593097
BNX2X_ERR("Unknown command: %d\n", cmd_pos->type);
29603098
return -EINVAL;
@@ -3095,6 +3233,19 @@ static int bnx2x_mcast_validate_e2(struct bnx2x *bp,
30953233
o->set_registry_size(o, reg_sz + p->mcast_list_len);
30963234
break;
30973235

3236+
case BNX2X_MCAST_CMD_SET:
3237+
/* We can only learn how many commands would actually be used
3238+
* when this is being configured. So for now, simply guarantee
3239+
* the command will be enqueued [to refrain from adding logic
3240+
* that handles this and THEN learns it needs several ramrods].
3241+
* Just like for ADD/Cont, the mcast_list_len might be an over
3242+
* estimation; or even more so, since we don't take into
3243+
* account the possibility of removal of existing bins.
3244+
*/
3245+
o->set_registry_size(o, reg_sz + p->mcast_list_len);
3246+
o->total_pending_num += o->max_cmd_len;
3247+
break;
3248+
30983249
default:
30993250
BNX2X_ERR("Unknown command: %d\n", cmd);
31003251
return -EINVAL;
@@ -3108,12 +3259,16 @@ static int bnx2x_mcast_validate_e2(struct bnx2x *bp,
31083259

31093260
static void bnx2x_mcast_revert_e2(struct bnx2x *bp,
31103261
struct bnx2x_mcast_ramrod_params *p,
3111-
int old_num_bins)
3262+
int old_num_bins,
3263+
enum bnx2x_mcast_cmd cmd)
31123264
{
31133265
struct bnx2x_mcast_obj *o = p->mcast_obj;
31143266

31153267
o->set_registry_size(o, old_num_bins);
31163268
o->total_pending_num -= p->mcast_list_len;
3269+
3270+
if (cmd == BNX2X_MCAST_CMD_SET)
3271+
o->total_pending_num -= o->max_cmd_len;
31173272
}
31183273

31193274
/**
@@ -3223,9 +3378,11 @@ static int bnx2x_mcast_setup_e2(struct bnx2x *bp,
32233378
bnx2x_mcast_refresh_registry_e2(bp, o);
32243379

32253380
/* If CLEAR_ONLY was requested - don't send a ramrod and clear
3226-
* RAMROD_PENDING status immediately.
3381+
* RAMROD_PENDING status immediately. due to the SET option, it's also
3382+
* possible that after evaluating the differences there's no need for
3383+
* a ramrod. In that case, we can skip it as well.
32273384
*/
3228-
if (test_bit(RAMROD_DRV_CLR_ONLY, &p->ramrod_flags)) {
3385+
if (test_bit(RAMROD_DRV_CLR_ONLY, &p->ramrod_flags) || !cnt) {
32293386
raw->clear_pending(raw);
32303387
return 0;
32313388
} else {
@@ -3253,6 +3410,11 @@ static int bnx2x_mcast_validate_e1h(struct bnx2x *bp,
32533410
struct bnx2x_mcast_ramrod_params *p,
32543411
enum bnx2x_mcast_cmd cmd)
32553412
{
3413+
if (cmd == BNX2X_MCAST_CMD_SET) {
3414+
BNX2X_ERR("Can't use `set' command on e1h!\n");
3415+
return -EINVAL;
3416+
}
3417+
32563418
/* Mark, that there is a work to do */
32573419
if ((cmd == BNX2X_MCAST_CMD_DEL) || (cmd == BNX2X_MCAST_CMD_RESTORE))
32583420
p->mcast_list_len = 1;
@@ -3262,7 +3424,8 @@ static int bnx2x_mcast_validate_e1h(struct bnx2x *bp,
32623424

32633425
static void bnx2x_mcast_revert_e1h(struct bnx2x *bp,
32643426
struct bnx2x_mcast_ramrod_params *p,
3265-
int old_num_bins)
3427+
int old_num_bins,
3428+
enum bnx2x_mcast_cmd cmd)
32663429
{
32673430
/* Do nothing */
32683431
}
@@ -3372,6 +3535,11 @@ static int bnx2x_mcast_validate_e1(struct bnx2x *bp,
33723535
struct bnx2x_mcast_obj *o = p->mcast_obj;
33733536
int reg_sz = o->get_registry_size(o);
33743537

3538+
if (cmd == BNX2X_MCAST_CMD_SET) {
3539+
BNX2X_ERR("Can't use `set' command on e1!\n");
3540+
return -EINVAL;
3541+
}
3542+
33753543
switch (cmd) {
33763544
/* DEL command deletes all currently configured MACs */
33773545
case BNX2X_MCAST_CMD_DEL:
@@ -3422,7 +3590,8 @@ static int bnx2x_mcast_validate_e1(struct bnx2x *bp,
34223590

34233591
static void bnx2x_mcast_revert_e1(struct bnx2x *bp,
34243592
struct bnx2x_mcast_ramrod_params *p,
3425-
int old_num_macs)
3593+
int old_num_macs,
3594+
enum bnx2x_mcast_cmd cmd)
34263595
{
34273596
struct bnx2x_mcast_obj *o = p->mcast_obj;
34283597

@@ -3816,7 +3985,7 @@ int bnx2x_config_mcast(struct bnx2x *bp,
38163985
r->clear_pending(r);
38173986

38183987
error_exit1:
3819-
o->revert(bp, p, old_reg_size);
3988+
o->revert(bp, p, old_reg_size, cmd);
38203989

38213990
return rc;
38223991
}

0 commit comments

Comments
 (0)