/** * struct nfp_flower_cmsg_lag_config - control message payload for LAG config * @ctrl_flags: Configuration flags * @reserved: Reserved for future use * @ttl: Time to live of packet - host always sets to 0xff * @pkt_number: Config message packet number - increment for each message * @batch_ver: Batch version of messages - increment for each batch of messages * @group_id: Group ID applicable * @group_inst: Group instance number - increment when group is reused * @members: Array of 32-bit words listing all active group members
*/ struct nfp_flower_cmsg_lag_config {
u8 ctrl_flags;
u8 reserved[2];
u8 ttl;
__be32 pkt_number;
__be32 batch_ver;
__be32 group_id;
__be32 group_inst;
__be32 members[];
};
/** * struct nfp_fl_lag_group - list entry for each LAG group * @group_id: Assigned group ID for host/kernel sync * @group_inst: Group instance in case of ID reuse * @list: List entry * @master_ndev: Group master Netdev * @dirty: Marked if the group needs synced to HW * @offloaded: Marked if the group is currently offloaded to NIC * @to_remove: Marked if the group should be removed from NIC * @to_destroy: Marked if the group should be removed from driver * @slave_cnt: Number of slaves in group
*/ struct nfp_fl_lag_group { unsignedint group_id;
u8 group_inst; struct list_head list; struct net_device *master_ndev; bool dirty; bool offloaded; bool to_remove; bool to_destroy; unsignedint slave_cnt;
};
/* Use this ID with zero members to ack a batch config */ #define NFP_FL_LAG_SYNC_ID 0 #define NFP_FL_LAG_GROUP_MIN 1 /* ID 0 reserved */ #define NFP_FL_LAG_GROUP_MAX 31 /* IDs 1 to 31 are valid */
/* wait for more config */ #define NFP_FL_LAG_DELAY (msecs_to_jiffies(2))
#define NFP_FL_LAG_RETRANS_LIMIT 100 /* max retrans cmsgs to store */
staticvoid nfp_fl_increment_version(struct nfp_fl_lag *lag)
{ /* LSB is not considered by firmware so add 2 for each increment. */
lag->batch_ver += 2;
lag->batch_ver &= NFP_FL_LAG_VERSION_MASK;
/* Zero is reserved by firmware. */ if (!lag->batch_ver)
lag->batch_ver += 2;
}
id = ida_alloc_range(&lag->ida_handle, NFP_FL_LAG_GROUP_MIN,
NFP_FL_LAG_GROUP_MAX, GFP_KERNEL); if (id < 0) {
nfp_flower_cmsg_warn(priv->app, "No more bonding groups available\n"); return ERR_PTR(id);
}
group = kmalloc(sizeof(*group), GFP_KERNEL); if (!group) {
ida_free(&lag->ida_handle, id); return ERR_PTR(-ENOMEM);
}
int nfp_flower_lag_populate_pre_action(struct nfp_app *app, struct net_device *master, struct nfp_fl_pre_lag *pre_act, struct netlink_ext_ack *extack)
{ if (nfp_fl_lag_get_group_info(app, master, &pre_act->group_id,
pre_act->lag_version,
&pre_act->instance)) {
NL_SET_ERR_MSG_MOD(extack, "invalid entry: group does not exist for LAG action"); return -ENOENT;
}
/* Increment batch version for each new batch of config messages. */ if (*batch == NFP_FL_LAG_BATCH_FIRST) {
flags |= NFP_FL_LAG_FIRST;
nfp_fl_increment_version(lag);
*batch = NFP_FL_LAG_BATCH_MEMBER;
}
/* If it is a reset msg then it is also the end of the batch. */ if (lag->rst_cfg) {
flags |= NFP_FL_LAG_RESET;
*batch = NFP_FL_LAG_BATCH_FINISHED;
}
/* To signal the end of a batch, both the switch and last flags are set * and the reserved SYNC group ID is used.
*/ if (*batch == NFP_FL_LAG_BATCH_FINISHED) {
flags |= NFP_FL_LAG_SWITCH | NFP_FL_LAG_LAST;
lag->rst_cfg = false;
cmsg_payload->group_id = cpu_to_be32(NFP_FL_LAG_SYNC_ID);
cmsg_payload->group_inst = 0;
} else {
cmsg_payload->group_id = cpu_to_be32(group->group_id);
cmsg_payload->group_inst = cpu_to_be32(group->group_inst);
}
/* Include sanity check in the loop. It may be that a bond has * changed between processing the last notification and the * work queue triggering. If the number of slaves has changed * or it now contains netdevs that cannot be offloaded, ignore * the group until pending notifications are processed.
*/
rcu_read_lock();
for_each_netdev_in_bond_rcu(entry->master_ndev, iter_netdev) { if (!nfp_netdev_is_nfp_repr(iter_netdev)) {
slaves = 0; break;
}
repr = netdev_priv(iter_netdev);
if (repr->app != priv->app) {
slaves = 0; break;
}
slaves++; if (slaves > entry->slave_cnt) break;
/* Check the ports for state changes. */
repr_priv = repr->app_priv;
flags = &repr_priv->lag_port_flags;
/* End the config batch if at least one packet has been batched. */ if (batch == NFP_FL_LAG_BATCH_MEMBER) {
batch = NFP_FL_LAG_BATCH_FINISHED;
err = nfp_fl_lag_config_group(lag, NULL, NULL, 0, &batch); if (err)
nfp_flower_cmsg_warn(priv->app, "group batch end cmsg failed\n");
}
cmsg_payload = nfp_flower_cmsg_get_data(skb); if (be32_to_cpu(cmsg_payload->group_id) > NFP_FL_LAG_GROUP_MAX) return -EINVAL;
/* Drop cmsg retrans if storage limit is exceeded to prevent * overloading. If the fw notices that expected messages have not been * received in a given time block, it will request a full resync.
*/ if (skb_queue_len(&lag->retrans_skbs) >= NFP_FL_LAG_RETRANS_LIMIT) return -ENOSPC;
/* Note the intentional fall through below. If DATA and XON are both * set, the message will stored and sent again with the rest of the * unprocessed messages list.
*/
/* Store */ if (flags & NFP_FL_LAG_DATA) if (!nfp_fl_lag_put_unprocessed(&priv->nfp_lag, skb))
store_skb = true;
/* Send stored */ if (flags & NFP_FL_LAG_XON)
nfp_fl_send_unprocessed(&priv->nfp_lag);
/* Resend all */ if (flags & NFP_FL_LAG_SYNC) { /* To resend all config: * 1) Clear all unprocessed messages * 2) Mark all groups dirty * 3) Reset NFP group config * 4) Schedule a LAG config update
*/
err = nfp_flower_lag_reset(&priv->nfp_lag); if (err)
nfp_flower_cmsg_warn(priv->app, "mem err in group reset msg\n");
mutex_unlock(&priv->nfp_lag.lock);
mutex_lock(&lag->lock);
group = nfp_fl_lag_find_group_for_master_with_lag(lag, upper);
if (slave_count == 0 || !can_offload) { /* Cannot offload the group - remove if previously offloaded. */ if (group && group->offloaded)
nfp_fl_lag_schedule_group_remove(lag, group);
mutex_unlock(&lag->lock); return 0;
}
if (!group) {
group = nfp_fl_lag_group_create(lag, upper); if (IS_ERR(group)) {
mutex_unlock(&lag->lock); return PTR_ERR(group);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.