Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b985f870 authored by Simon Horman's avatar Simon Horman Committed by David S. Miller
Browse files

nfp: process control messages in workqueue in flower app



Processing of control messages is not time-critical and future processing
of some messages will require taking the RTNL which is not possible
in a BH handler. It seems simplest to move all control message processing
to a workqueue.

Signed-off-by: default avatarSimon Horman <simon.horman@netronome.com>
Reviewed-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent cf9d0140
Loading
Loading
Loading
Loading
+23 −1
Original line number Original line Diff line number Diff line
@@ -34,10 +34,12 @@
#include <linux/bitfield.h>
#include <linux/bitfield.h>
#include <linux/netdevice.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/skbuff.h>
#include <linux/workqueue.h>
#include <net/dst_metadata.h>
#include <net/dst_metadata.h>


#include "main.h"
#include "main.h"
#include "../nfpcore/nfp_cpp.h"
#include "../nfpcore/nfp_cpp.h"
#include "../nfp_net.h"
#include "../nfp_net_repr.h"
#include "../nfp_net_repr.h"
#include "./cmsg.h"
#include "./cmsg.h"


@@ -155,7 +157,8 @@ nfp_flower_cmsg_portmod_rx(struct nfp_app *app, struct sk_buff *skb)
	rcu_read_unlock();
	rcu_read_unlock();
}
}


void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb)
static void
nfp_flower_cmsg_process_one_rx(struct nfp_app *app, struct sk_buff *skb)
{
{
	struct nfp_flower_cmsg_hdr *cmsg_hdr;
	struct nfp_flower_cmsg_hdr *cmsg_hdr;
	enum nfp_flower_cmsg_type_port type;
	enum nfp_flower_cmsg_type_port type;
@@ -184,3 +187,22 @@ void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb)
out:
out:
	dev_kfree_skb_any(skb);
	dev_kfree_skb_any(skb);
}
}

void nfp_flower_cmsg_process_rx(struct work_struct *work)
{
	struct nfp_flower_priv *priv;
	struct sk_buff *skb;

	priv = container_of(work, struct nfp_flower_priv, cmsg_work);

	while ((skb = skb_dequeue(&priv->cmsg_skbs)))
		nfp_flower_cmsg_process_one_rx(priv->nn->app, skb);
}

void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb)
{
	struct nfp_flower_priv *priv = app->priv;

	skb_queue_tail(&priv->cmsg_skbs, skb);
	schedule_work(&priv->cmsg_work);
}
+1 −0
Original line number Original line Diff line number Diff line
@@ -330,6 +330,7 @@ nfp_flower_cmsg_mac_repr_add(struct sk_buff *skb, unsigned int idx,
			     unsigned int nbi, unsigned int nbi_port,
			     unsigned int nbi, unsigned int nbi_port,
			     unsigned int phys_port);
			     unsigned int phys_port);
int nfp_flower_cmsg_portmod(struct nfp_repr *repr, bool carrier_ok);
int nfp_flower_cmsg_portmod(struct nfp_repr *repr, bool carrier_ok);
void nfp_flower_cmsg_process_rx(struct work_struct *work);
void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb);
void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb);
struct sk_buff *
struct sk_buff *
nfp_flower_cmsg_alloc(struct nfp_app *app, unsigned int size,
nfp_flower_cmsg_alloc(struct nfp_app *app, unsigned int size,
+12 −2
Original line number Original line Diff line number Diff line
@@ -332,6 +332,7 @@ static int nfp_flower_vnic_init(struct nfp_app *app, struct nfp_net *nn,
static int nfp_flower_init(struct nfp_app *app)
static int nfp_flower_init(struct nfp_app *app)
{
{
	const struct nfp_pf *pf = app->pf;
	const struct nfp_pf *pf = app->pf;
	struct nfp_flower_priv *app_priv;
	u64 version;
	u64 version;
	int err;
	int err;


@@ -362,10 +363,14 @@ static int nfp_flower_init(struct nfp_app *app)
		return -EINVAL;
		return -EINVAL;
	}
	}


	app->priv = vzalloc(sizeof(struct nfp_flower_priv));
	app_priv = vzalloc(sizeof(struct nfp_flower_priv));
	if (!app->priv)
	if (!app_priv)
		return -ENOMEM;
		return -ENOMEM;


	app->priv = app_priv;
	skb_queue_head_init(&app_priv->cmsg_skbs);
	INIT_WORK(&app_priv->cmsg_work, nfp_flower_cmsg_process_rx);

	err = nfp_flower_metadata_init(app);
	err = nfp_flower_metadata_init(app);
	if (err)
	if (err)
		goto err_free_app_priv;
		goto err_free_app_priv;
@@ -379,6 +384,11 @@ static int nfp_flower_init(struct nfp_app *app)


static void nfp_flower_clean(struct nfp_app *app)
static void nfp_flower_clean(struct nfp_app *app)
{
{
	struct nfp_flower_priv *app_priv = app->priv;

	skb_queue_purge(&app_priv->cmsg_skbs);
	flush_work(&app_priv->cmsg_work);

	nfp_flower_metadata_cleanup(app);
	nfp_flower_metadata_cleanup(app);
	vfree(app->priv);
	vfree(app->priv);
	app->priv = NULL;
	app->priv = NULL;
+5 −0
Original line number Original line Diff line number Diff line
@@ -39,6 +39,7 @@
#include <linux/time64.h>
#include <linux/time64.h>
#include <linux/types.h>
#include <linux/types.h>
#include <net/pkt_cls.h>
#include <net/pkt_cls.h>
#include <linux/workqueue.h>


struct net_device;
struct net_device;
struct nfp_app;
struct nfp_app;
@@ -78,6 +79,8 @@ struct nfp_fl_stats_id {
 * @mask_ids:		List of free mask ids
 * @mask_ids:		List of free mask ids
 * @mask_table:		Hash table used to store masks
 * @mask_table:		Hash table used to store masks
 * @flow_table:		Hash table used to store flower rules
 * @flow_table:		Hash table used to store flower rules
 * @cmsg_work:		Workqueue for control messages processing
 * @cmsg_skbs:		List of skbs for control message processing
 */
 */
struct nfp_flower_priv {
struct nfp_flower_priv {
	struct nfp_net *nn;
	struct nfp_net *nn;
@@ -87,6 +90,8 @@ struct nfp_flower_priv {
	struct nfp_fl_mask_id mask_ids;
	struct nfp_fl_mask_id mask_ids;
	DECLARE_HASHTABLE(mask_table, NFP_FLOWER_MASK_HASH_BITS);
	DECLARE_HASHTABLE(mask_table, NFP_FLOWER_MASK_HASH_BITS);
	DECLARE_HASHTABLE(flow_table, NFP_FLOWER_HASH_BITS);
	DECLARE_HASHTABLE(flow_table, NFP_FLOWER_HASH_BITS);
	struct work_struct cmsg_work;
	struct sk_buff_head cmsg_skbs;
};
};


struct nfp_fl_key_ls {
struct nfp_fl_key_ls {