netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Matthew Wilcox <willy@infradead.org>
To: netdev@vger.kernel.org
Cc: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Subject: [PATCH 18/38] rxrpc: Convert to XArray
Date: Tue, 20 Aug 2019 15:32:39 -0700	[thread overview]
Message-ID: <20190820223259.22348-19-willy@infradead.org> (raw)
In-Reply-To: <20190820223259.22348-1-willy@infradead.org>

From: "Matthew Wilcox (Oracle)" <willy@infradead.org>

The XArray requires a separate cursor, but embeds the lock, so it's
a minor saving.  Also, there's no need to preload.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
 net/rxrpc/af_rxrpc.c    |  2 +-
 net/rxrpc/ar-internal.h |  3 ++-
 net/rxrpc/conn_client.c | 49 +++++++++++++++--------------------------
 net/rxrpc/conn_object.c |  2 +-
 4 files changed, 22 insertions(+), 34 deletions(-)

diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c
index d09eaf153544..16e289bbc825 100644
--- a/net/rxrpc/af_rxrpc.c
+++ b/net/rxrpc/af_rxrpc.c
@@ -981,7 +981,7 @@ static int __init af_rxrpc_init(void)
 	tmp &= 0x3fffffff;
 	if (tmp == 0)
 		tmp = 1;
-	idr_set_cursor(&rxrpc_client_conn_ids, tmp);
+	rxrpc_client_conn_next = tmp;
 
 	ret = -ENOMEM;
 	rxrpc_call_jar = kmem_cache_create(
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
index 63b26baa108a..7721448aa7a4 100644
--- a/net/rxrpc/ar-internal.h
+++ b/net/rxrpc/ar-internal.h
@@ -898,7 +898,8 @@ extern unsigned int rxrpc_max_client_connections;
 extern unsigned int rxrpc_reap_client_connections;
 extern unsigned long rxrpc_conn_idle_client_expiry;
 extern unsigned long rxrpc_conn_idle_client_fast_expiry;
-extern struct idr rxrpc_client_conn_ids;
+extern struct xarray rxrpc_client_conn_ids;
+extern u32 rxrpc_client_conn_next;
 
 void rxrpc_destroy_client_conn_ids(void);
 int rxrpc_connect_call(struct rxrpc_sock *, struct rxrpc_call *,
diff --git a/net/rxrpc/conn_client.c b/net/rxrpc/conn_client.c
index aea82f909c60..d967de7a5eb9 100644
--- a/net/rxrpc/conn_client.c
+++ b/net/rxrpc/conn_client.c
@@ -72,7 +72,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/slab.h>
-#include <linux/idr.h>
+#include <linux/xarray.h>
 #include <linux/timer.h>
 #include <linux/sched/signal.h>
 
@@ -86,14 +86,14 @@ __read_mostly unsigned long rxrpc_conn_idle_client_fast_expiry = 2 * HZ;
 /*
  * We use machine-unique IDs for our client connections.
  */
-DEFINE_IDR(rxrpc_client_conn_ids);
-static DEFINE_SPINLOCK(rxrpc_conn_id_lock);
+DEFINE_XARRAY_ALLOC1(rxrpc_client_conn_ids);
+u32 rxrpc_client_conn_next;
 
 static void rxrpc_cull_active_client_conns(struct rxrpc_net *);
 
 /*
  * Get a connection ID and epoch for a client connection from the global pool.
- * The connection struct pointer is then recorded in the idr radix tree.  The
+ * The connection struct pointer is then recorded in the XArray.  The
  * epoch doesn't change until the client is rebooted (or, at least, unless the
  * module is unloaded).
  */
@@ -101,21 +101,15 @@ static int rxrpc_get_client_connection_id(struct rxrpc_connection *conn,
 					  gfp_t gfp)
 {
 	struct rxrpc_net *rxnet = conn->params.local->rxnet;
-	int id;
+	int err, id;
 
 	_enter("");
 
-	idr_preload(gfp);
-	spin_lock(&rxrpc_conn_id_lock);
-
-	id = idr_alloc_cyclic(&rxrpc_client_conn_ids, conn,
-			      1, 0x40000000, GFP_NOWAIT);
-	if (id < 0)
+	err = xa_alloc_cyclic(&rxrpc_client_conn_ids, &id, conn,
+			XA_LIMIT(1, 0x40000000), &rxrpc_client_conn_next, gfp);
+	if (err < 0)
 		goto error;
 
-	spin_unlock(&rxrpc_conn_id_lock);
-	idr_preload_end();
-
 	conn->proto.epoch = rxnet->epoch;
 	conn->proto.cid = id << RXRPC_CIDSHIFT;
 	set_bit(RXRPC_CONN_HAS_IDR, &conn->flags);
@@ -123,10 +117,8 @@ static int rxrpc_get_client_connection_id(struct rxrpc_connection *conn,
 	return 0;
 
 error:
-	spin_unlock(&rxrpc_conn_id_lock);
-	idr_preload_end();
-	_leave(" = %d", id);
-	return id;
+	_leave(" = %d", err);
+	return err;
 }
 
 /*
@@ -135,30 +127,26 @@ static int rxrpc_get_client_connection_id(struct rxrpc_connection *conn,
 static void rxrpc_put_client_connection_id(struct rxrpc_connection *conn)
 {
 	if (test_bit(RXRPC_CONN_HAS_IDR, &conn->flags)) {
-		spin_lock(&rxrpc_conn_id_lock);
-		idr_remove(&rxrpc_client_conn_ids,
+		xa_erase(&rxrpc_client_conn_ids,
 			   conn->proto.cid >> RXRPC_CIDSHIFT);
-		spin_unlock(&rxrpc_conn_id_lock);
 	}
 }
 
 /*
- * Destroy the client connection ID tree.
+ * There should be no outstanding client connections.
  */
 void rxrpc_destroy_client_conn_ids(void)
 {
-	struct rxrpc_connection *conn;
-	int id;
+	if (!xa_empty(&rxrpc_client_conn_ids)) {
+		struct rxrpc_connection *conn;
+		unsigned long id;
 
-	if (!idr_is_empty(&rxrpc_client_conn_ids)) {
-		idr_for_each_entry(&rxrpc_client_conn_ids, conn, id) {
+		xa_for_each(&rxrpc_client_conn_ids, id, conn) {
 			pr_err("AF_RXRPC: Leaked client conn %p {%d}\n",
 			       conn, atomic_read(&conn->usage));
 		}
 		BUG();
 	}
-
-	idr_destroy(&rxrpc_client_conn_ids);
 }
 
 /*
@@ -234,7 +222,7 @@ rxrpc_alloc_client_connection(struct rxrpc_conn_parameters *cp, gfp_t gfp)
 static bool rxrpc_may_reuse_conn(struct rxrpc_connection *conn)
 {
 	struct rxrpc_net *rxnet = conn->params.local->rxnet;
-	int id_cursor, id, distance, limit;
+	int id, distance, limit;
 
 	if (test_bit(RXRPC_CONN_DONT_REUSE, &conn->flags))
 		goto dont_reuse;
@@ -248,9 +236,8 @@ static bool rxrpc_may_reuse_conn(struct rxrpc_connection *conn)
 	 * times the maximum number of client conns away from the current
 	 * allocation point to try and keep the IDs concentrated.
 	 */
-	id_cursor = idr_get_cursor(&rxrpc_client_conn_ids);
 	id = conn->proto.cid >> RXRPC_CIDSHIFT;
-	distance = id - id_cursor;
+	distance = id - rxrpc_client_conn_next;
 	if (distance < 0)
 		distance = -distance;
 	limit = max(rxrpc_max_client_connections * 4, 1024U);
diff --git a/net/rxrpc/conn_object.c b/net/rxrpc/conn_object.c
index 434ef392212b..31eef9c2a9ac 100644
--- a/net/rxrpc/conn_object.c
+++ b/net/rxrpc/conn_object.c
@@ -115,7 +115,7 @@ struct rxrpc_connection *rxrpc_find_connection_rcu(struct rxrpc_local *local,
 		/* Look up client connections by connection ID alone as their
 		 * IDs are unique for this machine.
 		 */
-		conn = idr_find(&rxrpc_client_conn_ids,
+		conn = xa_load(&rxrpc_client_conn_ids,
 				sp->hdr.cid >> RXRPC_CIDSHIFT);
 		if (!conn || atomic_read(&conn->usage) == 0) {
 			_debug("no conn");
-- 
2.23.0.rc1


  parent reply	other threads:[~2019-08-20 22:33 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-20 22:32 [PATCH 00/38] Convert networking to use the XArray Matthew Wilcox
2019-08-20 22:32 ` [PATCH 01/38] mlx4: Convert cq_table->tree to XArray Matthew Wilcox
2019-08-20 22:32 ` [PATCH 02/38] mlx4: Convert srq_table->tree " Matthew Wilcox
2019-08-20 22:32 ` [PATCH 03/38] mlx4: Convert qp_table_tree " Matthew Wilcox
2019-08-27 19:18   ` Saeed Mahameed
2019-08-20 22:32 ` [PATCH 04/38] mlx5: Convert cq_table " Matthew Wilcox
2019-08-27 19:22   ` Saeed Mahameed
2019-08-20 22:32 ` [PATCH 05/38] mlx5: Convert mlx5_qp_table " Matthew Wilcox
2019-08-20 22:32 ` [PATCH 06/38] mlx5: Convert counters_idr " Matthew Wilcox
2019-08-20 22:32 ` [PATCH 07/38] mlx5: Convert fpga IDRs " Matthew Wilcox
2019-08-20 22:32 ` [PATCH 08/38] nfp: Convert " Matthew Wilcox
2019-08-21  3:59   ` Jakub Kicinski
2019-08-20 22:32 ` [PATCH 09/38] ath10k: Convert pending_tx " Matthew Wilcox
2019-08-20 22:32 ` [PATCH 10/38] ath10k: Convert mgmt_pending_tx IDR " Matthew Wilcox
2019-08-20 22:32 ` [PATCH 11/38] mt76: Convert token " Matthew Wilcox
2019-08-20 22:32 ` [PATCH 12/38] mwifiex: Convert ack_status_frames " Matthew Wilcox
2019-08-20 22:32 ` [PATCH 13/38] ppp: Convert units_idr " Matthew Wilcox
2019-08-20 22:32 ` [PATCH 14/38] tap: Convert minor_idr " Matthew Wilcox
2019-08-20 22:32 ` [PATCH 15/38] nfp: Convert internal ports " Matthew Wilcox
2019-08-20 22:32 ` [PATCH 16/38] qrtr: Convert qrtr_nodes " Matthew Wilcox
2019-08-20 22:32 ` [PATCH 17/38] qrtr: Convert qrtr_ports " Matthew Wilcox
2019-08-20 22:32 ` Matthew Wilcox [this message]
2019-08-20 22:32 ` [PATCH 19/38] 9p: Convert reqs IDR " Matthew Wilcox
2019-08-20 22:32 ` [PATCH 20/38] 9p: Convert fids " Matthew Wilcox
2019-08-20 22:32 ` [PATCH 21/38] 9p: Move lock from client to trans_fd Matthew Wilcox
2019-08-20 22:32 ` [PATCH 22/38] sctp: Convert sctp_assocs_id to XArray Matthew Wilcox
2019-08-20 22:32 ` [PATCH 23/38] cls_api: Convert tcf_net " Matthew Wilcox
2019-08-20 23:57   ` David Miller
2019-08-21  0:52     ` Matthew Wilcox
2019-08-20 22:32 ` [PATCH 24/38] cls_u32: Convert tc_u_common->handle_idr " Matthew Wilcox
2019-08-21 21:13   ` Jakub Kicinski
2019-08-21 21:25     ` Matthew Wilcox
2019-08-21 21:38       ` Jakub Kicinski
2019-08-20 22:32 ` [PATCH 25/38] cls_u32: Convert tc_u_hnode->handle_idr " Matthew Wilcox
2019-08-20 22:32 ` [PATCH 26/38] cls_bpf: Convert handle_idr " Matthew Wilcox
2019-08-20 22:32 ` [PATCH 27/38] cls_bpf: Remove list of programs Matthew Wilcox
2019-08-20 22:32 ` [PATCH 28/38] cls_bpf: Use XArray marks to accelerate re-offload Matthew Wilcox
2019-08-20 22:32 ` [PATCH 29/38] cls_flower: Convert handle_idr to XArray Matthew Wilcox
2019-08-20 23:58   ` David Miller
2019-08-21  0:50     ` Matthew Wilcox
2019-08-21 18:27   ` Vlad Buslov
2019-08-25 18:32     ` Cong Wang
2019-08-26 10:11       ` Vlad Buslov
2019-08-20 22:32 ` [PATCH 30/38] cls_flower: Use XArray list of filters in fl_walk Matthew Wilcox
2019-08-21 18:32   ` Vlad Buslov
2019-08-20 22:32 ` [PATCH 31/38] cls_flower: Use XArray marks instead of separate list Matthew Wilcox
2019-08-21 19:12   ` Vlad Buslov
2019-08-20 22:32 ` [PATCH 32/38] cls_basic: Convert handle_idr to XArray Matthew Wilcox
2019-08-20 22:32 ` [PATCH 33/38] act_api: Convert action_idr " Matthew Wilcox
2019-08-21 19:41   ` Vlad Buslov
2019-08-21 20:35     ` Matthew Wilcox
2019-08-20 22:32 ` [PATCH 34/38] net_namespace: Convert netns_ids " Matthew Wilcox
2019-08-20 22:32 ` [PATCH 35/38] tipc: Convert conn_idr " Matthew Wilcox
2019-08-20 22:32 ` [PATCH 36/38] netlink: Convert genl_fam_idr " Matthew Wilcox
2019-08-20 22:32 ` [PATCH 37/38] mac80211: Convert ack_status_frames " Matthew Wilcox
2019-08-20 22:32 ` [PATCH 38/38] mac80211: Convert function_inst_ids " Matthew Wilcox

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190820223259.22348-19-willy@infradead.org \
    --to=willy@infradead.org \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).