From: "Matthew Wilcox (Oracle)" <wi...@infradead.org> Since nfp_fl_internal_ports was only an IDR and the lock to protect it, replace the entire data structure with an XArray (which has an embedded lock).
Signed-off-by: Matthew Wilcox (Oracle) <wi...@infradead.org> --- .../net/ethernet/netronome/nfp/flower/main.c | 44 +++++++------------ .../net/ethernet/netronome/nfp/flower/main.h | 12 +---- 2 files changed, 17 insertions(+), 39 deletions(-) diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.c b/drivers/net/ethernet/netronome/nfp/flower/main.c index 7a20447cca19..706ae41645f5 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.c +++ b/drivers/net/ethernet/netronome/nfp/flower/main.c @@ -40,35 +40,31 @@ nfp_flower_lookup_internal_port_id(struct nfp_flower_priv *priv, struct net_device *netdev) { struct net_device *entry; - int i, id = 0; + unsigned long i; - rcu_read_lock(); - idr_for_each_entry(&priv->internal_ports.port_ids, entry, i) - if (entry == netdev) { - id = i; - break; - } - rcu_read_unlock(); + xa_for_each(&priv->internal_ports, i, entry) { + if (entry == netdev) + return i; + } - return id; + return 0; } static int nfp_flower_get_internal_port_id(struct nfp_app *app, struct net_device *netdev) { struct nfp_flower_priv *priv = app->priv; - int id; + int err, id; id = nfp_flower_lookup_internal_port_id(priv, netdev); if (id > 0) return id; - idr_preload(GFP_ATOMIC); - spin_lock_bh(&priv->internal_ports.lock); - id = idr_alloc(&priv->internal_ports.port_ids, netdev, - NFP_MIN_INT_PORT_ID, NFP_MAX_INT_PORT_ID, GFP_ATOMIC); - spin_unlock_bh(&priv->internal_ports.lock); - idr_preload_end(); + err = xa_alloc_bh(&priv->internal_ports, &id, netdev, + XA_LIMIT(NFP_MIN_INT_PORT_ID, NFP_MAX_INT_PORT_ID), + GFP_ATOMIC); + if (err < 0) + return err; return id; } @@ -95,13 +91,8 @@ static struct net_device * nfp_flower_get_netdev_from_internal_port_id(struct nfp_app *app, int port_id) { struct nfp_flower_priv *priv = app->priv; - struct net_device *netdev; - - rcu_read_lock(); - netdev = idr_find(&priv->internal_ports.port_ids, port_id); - rcu_read_unlock(); - return netdev; + return xa_load(&priv->internal_ports, port_id); } static void @@ -114,9 +105,7 @@ nfp_flower_free_internal_port_id(struct nfp_app *app, struct net_device *netdev) if (!id) return; - spin_lock_bh(&priv->internal_ports.lock); - idr_remove(&priv->internal_ports.port_ids, id); - spin_unlock_bh(&priv->internal_ports.lock); + xa_erase_bh(&priv->internal_ports, id); } static int @@ -133,13 +122,12 @@ nfp_flower_internal_port_event_handler(struct nfp_app *app, static void nfp_flower_internal_port_init(struct nfp_flower_priv *priv) { - spin_lock_init(&priv->internal_ports.lock); - idr_init(&priv->internal_ports.port_ids); + xa_init_flags(&priv->internal_ports, XA_FLAGS_ALLOC | XA_FLAGS_LOCK_BH); } static void nfp_flower_internal_port_cleanup(struct nfp_flower_priv *priv) { - idr_destroy(&priv->internal_ports.port_ids); + xa_destroy(&priv->internal_ports); } static struct nfp_flower_non_repr_priv * diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h b/drivers/net/ethernet/netronome/nfp/flower/main.h index 31d94592a7c0..735e995ae740 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.h +++ b/drivers/net/ethernet/netronome/nfp/flower/main.h @@ -119,16 +119,6 @@ struct nfp_fl_lag { struct sk_buff_head retrans_skbs; }; -/** - * struct nfp_fl_internal_ports - Flower APP priv data for additional ports - * @port_ids: Assignment of ids to any additional ports - * @lock: Lock for extra ports list - */ -struct nfp_fl_internal_ports { - struct idr port_ids; - spinlock_t lock; -}; - /** * struct nfp_flower_priv - Flower APP per-vNIC priv data * @app: Back pointer to app @@ -191,7 +181,7 @@ struct nfp_flower_priv { struct list_head non_repr_priv; unsigned int active_mem_unit; unsigned int total_mem_units; - struct nfp_fl_internal_ports internal_ports; + struct xarray internal_ports; struct delayed_work qos_stats_work; unsigned int qos_rate_limiters; spinlock_t qos_stats_lock; /* Protect the qos stats */ -- 2.23.0.rc1