Skip to content

Commit cf2cbad

Browse files
pjvuurendavem330
authored andcommitted
nfp: flower: split and limit cmsg skb lists
Introduce a second skb list for handling control messages and limit the number of allowed messages. Some control messages are considered more crucial than others, resulting in the need for a second skb list. By splitting the list into a separate high and low priority list we can ensure that messages on the high list get added to the head of the list that gets processed, this however has no functional impact. Previously there was no limit on the number of messages allowed on the queue, this could result in the queue growing boundlessly and eventually the host running out of memory. Fixes: b985f87 ("nfp: process control messages in workqueue in flower app") Signed-off-by: Pieter Jansen van Vuuren <[email protected]> Reviewed-by: Jakub Kicinski <[email protected]> Reviewed-by: Simon Horman <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 0b1a989 commit cf2cbad

File tree

4 files changed

+46
-8
lines changed

4 files changed

+46
-8
lines changed

drivers/net/ethernet/netronome/nfp/flower/cmsg.c

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -272,18 +272,49 @@ nfp_flower_cmsg_process_one_rx(struct nfp_app *app, struct sk_buff *skb)
272272

273273
void nfp_flower_cmsg_process_rx(struct work_struct *work)
274274
{
275+
struct sk_buff_head cmsg_joined;
275276
struct nfp_flower_priv *priv;
276277
struct sk_buff *skb;
277278

278279
priv = container_of(work, struct nfp_flower_priv, cmsg_work);
280+
skb_queue_head_init(&cmsg_joined);
279281

280-
while ((skb = skb_dequeue(&priv->cmsg_skbs)))
282+
spin_lock_bh(&priv->cmsg_skbs_high.lock);
283+
skb_queue_splice_tail_init(&priv->cmsg_skbs_high, &cmsg_joined);
284+
spin_unlock_bh(&priv->cmsg_skbs_high.lock);
285+
286+
spin_lock_bh(&priv->cmsg_skbs_low.lock);
287+
skb_queue_splice_tail_init(&priv->cmsg_skbs_low, &cmsg_joined);
288+
spin_unlock_bh(&priv->cmsg_skbs_low.lock);
289+
290+
while ((skb = __skb_dequeue(&cmsg_joined)))
281291
nfp_flower_cmsg_process_one_rx(priv->app, skb);
282292
}
283293

284-
void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb)
294+
static void
295+
nfp_flower_queue_ctl_msg(struct nfp_app *app, struct sk_buff *skb, int type)
285296
{
286297
struct nfp_flower_priv *priv = app->priv;
298+
struct sk_buff_head *skb_head;
299+
300+
if (type == NFP_FLOWER_CMSG_TYPE_PORT_REIFY ||
301+
type == NFP_FLOWER_CMSG_TYPE_PORT_MOD)
302+
skb_head = &priv->cmsg_skbs_high;
303+
else
304+
skb_head = &priv->cmsg_skbs_low;
305+
306+
if (skb_queue_len(skb_head) >= NFP_FLOWER_WORKQ_MAX_SKBS) {
307+
nfp_flower_cmsg_warn(app, "Dropping queued control messages\n");
308+
dev_kfree_skb_any(skb);
309+
return;
310+
}
311+
312+
skb_queue_tail(skb_head, skb);
313+
schedule_work(&priv->cmsg_work);
314+
}
315+
316+
void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb)
317+
{
287318
struct nfp_flower_cmsg_hdr *cmsg_hdr;
288319

289320
cmsg_hdr = nfp_flower_cmsg_get_hdr(skb);
@@ -307,7 +338,6 @@ void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb)
307338
/* Acks from the NFP that the route is added - ignore. */
308339
dev_consume_skb_any(skb);
309340
} else {
310-
skb_queue_tail(&priv->cmsg_skbs, skb);
311-
schedule_work(&priv->cmsg_work);
341+
nfp_flower_queue_ctl_msg(app, skb, cmsg_hdr->type);
312342
}
313343
}

drivers/net/ethernet/netronome/nfp/flower/cmsg.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@
108108
#define NFP_FL_IPV4_TUNNEL_TYPE GENMASK(7, 4)
109109
#define NFP_FL_IPV4_PRE_TUN_INDEX GENMASK(2, 0)
110110

111+
#define NFP_FLOWER_WORKQ_MAX_SKBS 30000
112+
111113
#define nfp_flower_cmsg_warn(app, fmt, args...) \
112114
do { \
113115
if (net_ratelimit()) \

drivers/net/ethernet/netronome/nfp/flower/main.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,8 @@ static int nfp_flower_init(struct nfp_app *app)
519519

520520
app->priv = app_priv;
521521
app_priv->app = app;
522-
skb_queue_head_init(&app_priv->cmsg_skbs);
522+
skb_queue_head_init(&app_priv->cmsg_skbs_high);
523+
skb_queue_head_init(&app_priv->cmsg_skbs_low);
523524
INIT_WORK(&app_priv->cmsg_work, nfp_flower_cmsg_process_rx);
524525
init_waitqueue_head(&app_priv->reify_wait_queue);
525526

@@ -549,7 +550,8 @@ static void nfp_flower_clean(struct nfp_app *app)
549550
{
550551
struct nfp_flower_priv *app_priv = app->priv;
551552

552-
skb_queue_purge(&app_priv->cmsg_skbs);
553+
skb_queue_purge(&app_priv->cmsg_skbs_high);
554+
skb_queue_purge(&app_priv->cmsg_skbs_low);
553555
flush_work(&app_priv->cmsg_work);
554556

555557
nfp_flower_metadata_cleanup(app);

drivers/net/ethernet/netronome/nfp/flower/main.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,10 @@ struct nfp_mtu_conf {
107107
* @mask_table: Hash table used to store masks
108108
* @flow_table: Hash table used to store flower rules
109109
* @cmsg_work: Workqueue for control messages processing
110-
* @cmsg_skbs: List of skbs for control message processing
110+
* @cmsg_skbs_high: List of higher priority skbs for control message
111+
* processing
112+
* @cmsg_skbs_low: List of lower priority skbs for control message
113+
* processing
111114
* @nfp_mac_off_list: List of MAC addresses to offload
112115
* @nfp_mac_index_list: List of unique 8-bit indexes for non NFP netdevs
113116
* @nfp_ipv4_off_list: List of IPv4 addresses to offload
@@ -136,7 +139,8 @@ struct nfp_flower_priv {
136139
DECLARE_HASHTABLE(mask_table, NFP_FLOWER_MASK_HASH_BITS);
137140
DECLARE_HASHTABLE(flow_table, NFP_FLOWER_HASH_BITS);
138141
struct work_struct cmsg_work;
139-
struct sk_buff_head cmsg_skbs;
142+
struct sk_buff_head cmsg_skbs_high;
143+
struct sk_buff_head cmsg_skbs_low;
140144
struct list_head nfp_mac_off_list;
141145
struct list_head nfp_mac_index_list;
142146
struct list_head nfp_ipv4_off_list;

0 commit comments

Comments
 (0)