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

Reply via email to