aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Wilcox <willy@infradead.org>2018-07-11 17:02:22 -0400
committerDominique Martinet <dominique.martinet@cea.fr>2018-08-12 20:21:44 -0400
commitf28cdf0430fc92acaa718e15598bdad6cb236a4d (patch)
tree26c62e06986d2a7a46680c272b2db065cda9a38c
parentb5303be2bee3c8b29de3f7f4ea8ae00c4e816760 (diff)
9p: Replace the fidlist with an IDR
The p9_idpool being used to allocate the IDs uses an IDR to allocate the IDs ... which we then keep in a doubly-linked list, rather than in the IDR which allocated them. We can use an IDR directly which saves two pointers per p9_fid, and a tiny memory allocation per p9_client. Link: http://lkml.kernel.org/r/20180711210225.19730-4-willy@infradead.org Signed-off-by: Matthew Wilcox <willy@infradead.org> Cc: Eric Van Hensbergen <ericvh@gmail.com> Cc: Ron Minnich <rminnich@sandia.gov> Cc: Latchesar Ionkov <lucho@ionkov.net> Signed-off-by: Dominique Martinet <dominique.martinet@cea.fr>
-rw-r--r--include/net/9p/client.h9
-rw-r--r--net/9p/client.c44
2 files changed, 19 insertions, 34 deletions
diff --git a/include/net/9p/client.h b/include/net/9p/client.h
index 7af9d769b97d..e405729cd1c7 100644
--- a/include/net/9p/client.h
+++ b/include/net/9p/client.h
@@ -27,6 +27,7 @@
27#define NET_9P_CLIENT_H 27#define NET_9P_CLIENT_H
28 28
29#include <linux/utsname.h> 29#include <linux/utsname.h>
30#include <linux/idr.h>
30 31
31/* Number of requests per row */ 32/* Number of requests per row */
32#define P9_ROW_MAXTAG 255 33#define P9_ROW_MAXTAG 255
@@ -128,8 +129,7 @@ struct p9_req_t {
128 * @proto_version: 9P protocol version to use 129 * @proto_version: 9P protocol version to use
129 * @trans_mod: module API instantiated with this client 130 * @trans_mod: module API instantiated with this client
130 * @trans: tranport instance state and API 131 * @trans: tranport instance state and API
131 * @fidpool: fid handle accounting for session 132 * @fids: All active FID handles
132 * @fidlist: List of active fid handles
133 * @tagpool - transaction id accounting for session 133 * @tagpool - transaction id accounting for session
134 * @reqs - 2D array of requests 134 * @reqs - 2D array of requests
135 * @max_tag - current maximum tag id allocated 135 * @max_tag - current maximum tag id allocated
@@ -169,8 +169,7 @@ struct p9_client {
169 } tcp; 169 } tcp;
170 } trans_opts; 170 } trans_opts;
171 171
172 struct p9_idpool *fidpool; 172 struct idr fids;
173 struct list_head fidlist;
174 173
175 struct p9_idpool *tagpool; 174 struct p9_idpool *tagpool;
176 struct p9_req_t *reqs[P9_ROW_MAXTAG]; 175 struct p9_req_t *reqs[P9_ROW_MAXTAG];
@@ -188,7 +187,6 @@ struct p9_client {
188 * @iounit: the server reported maximum transaction size for this file 187 * @iounit: the server reported maximum transaction size for this file
189 * @uid: the numeric uid of the local user who owns this handle 188 * @uid: the numeric uid of the local user who owns this handle
190 * @rdir: readdir accounting structure (allocated on demand) 189 * @rdir: readdir accounting structure (allocated on demand)
191 * @flist: per-client-instance fid tracking
192 * @dlist: per-dentry fid tracking 190 * @dlist: per-dentry fid tracking
193 * 191 *
194 * TODO: This needs lots of explanation. 192 * TODO: This needs lots of explanation.
@@ -204,7 +202,6 @@ struct p9_fid {
204 202
205 void *rdir; 203 void *rdir;
206 204
207 struct list_head flist;
208 struct hlist_node dlist; /* list of all fids attached to a dentry */ 205 struct hlist_node dlist; /* list of all fids attached to a dentry */
209}; 206};
210 207
diff --git a/net/9p/client.c b/net/9p/client.c
index 7c317d39bf62..cd33cf636c47 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -909,30 +909,29 @@ static struct p9_fid *p9_fid_create(struct p9_client *clnt)
909{ 909{
910 int ret; 910 int ret;
911 struct p9_fid *fid; 911 struct p9_fid *fid;
912 unsigned long flags;
913 912
914 p9_debug(P9_DEBUG_FID, "clnt %p\n", clnt); 913 p9_debug(P9_DEBUG_FID, "clnt %p\n", clnt);
915 fid = kmalloc(sizeof(struct p9_fid), GFP_KERNEL); 914 fid = kmalloc(sizeof(struct p9_fid), GFP_KERNEL);
916 if (!fid) 915 if (!fid)
917 return NULL; 916 return NULL;
918 917
919 ret = p9_idpool_get(clnt->fidpool);
920 if (ret < 0)
921 goto error;
922 fid->fid = ret;
923
924 memset(&fid->qid, 0, sizeof(struct p9_qid)); 918 memset(&fid->qid, 0, sizeof(struct p9_qid));
925 fid->mode = -1; 919 fid->mode = -1;
926 fid->uid = current_fsuid(); 920 fid->uid = current_fsuid();
927 fid->clnt = clnt; 921 fid->clnt = clnt;
928 fid->rdir = NULL; 922 fid->rdir = NULL;
929 spin_lock_irqsave(&clnt->lock, flags); 923 fid->fid = 0;
930 list_add(&fid->flist, &clnt->fidlist);
931 spin_unlock_irqrestore(&clnt->lock, flags);
932 924
933 return fid; 925 idr_preload(GFP_KERNEL);
926 spin_lock_irq(&clnt->lock);
927 ret = idr_alloc_u32(&clnt->fids, fid, &fid->fid, P9_NOFID - 1,
928 GFP_NOWAIT);
929 spin_unlock_irq(&clnt->lock);
930 idr_preload_end();
931
932 if (!ret)
933 return fid;
934 934
935error:
936 kfree(fid); 935 kfree(fid);
937 return NULL; 936 return NULL;
938} 937}
@@ -944,9 +943,8 @@ static void p9_fid_destroy(struct p9_fid *fid)
944 943
945 p9_debug(P9_DEBUG_FID, "fid %d\n", fid->fid); 944 p9_debug(P9_DEBUG_FID, "fid %d\n", fid->fid);
946 clnt = fid->clnt; 945 clnt = fid->clnt;
947 p9_idpool_put(fid->fid, clnt->fidpool);
948 spin_lock_irqsave(&clnt->lock, flags); 946 spin_lock_irqsave(&clnt->lock, flags);
949 list_del(&fid->flist); 947 idr_remove(&clnt->fids, fid->fid);
950 spin_unlock_irqrestore(&clnt->lock, flags); 948 spin_unlock_irqrestore(&clnt->lock, flags);
951 kfree(fid->rdir); 949 kfree(fid->rdir);
952 kfree(fid); 950 kfree(fid);
@@ -1029,7 +1027,7 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
1029 memcpy(clnt->name, client_id, strlen(client_id) + 1); 1027 memcpy(clnt->name, client_id, strlen(client_id) + 1);
1030 1028
1031 spin_lock_init(&clnt->lock); 1029 spin_lock_init(&clnt->lock);
1032 INIT_LIST_HEAD(&clnt->fidlist); 1030 idr_init(&clnt->fids);
1033 1031
1034 err = p9_tag_init(clnt); 1032 err = p9_tag_init(clnt);
1035 if (err < 0) 1033 if (err < 0)
@@ -1049,18 +1047,12 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
1049 goto destroy_tagpool; 1047 goto destroy_tagpool;
1050 } 1048 }
1051 1049
1052 clnt->fidpool = p9_idpool_create();
1053 if (IS_ERR(clnt->fidpool)) {
1054 err = PTR_ERR(clnt->fidpool);
1055 goto put_trans;
1056 }
1057
1058 p9_debug(P9_DEBUG_MUX, "clnt %p trans %p msize %d protocol %d\n", 1050 p9_debug(P9_DEBUG_MUX, "clnt %p trans %p msize %d protocol %d\n",
1059 clnt, clnt->trans_mod, clnt->msize, clnt->proto_version); 1051 clnt, clnt->trans_mod, clnt->msize, clnt->proto_version);
1060 1052
1061 err = clnt->trans_mod->create(clnt, dev_name, options); 1053 err = clnt->trans_mod->create(clnt, dev_name, options);
1062 if (err) 1054 if (err)
1063 goto destroy_fidpool; 1055 goto put_trans;
1064 1056
1065 if (clnt->msize > clnt->trans_mod->maxsize) 1057 if (clnt->msize > clnt->trans_mod->maxsize)
1066 clnt->msize = clnt->trans_mod->maxsize; 1058 clnt->msize = clnt->trans_mod->maxsize;
@@ -1073,8 +1065,6 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
1073 1065
1074close_trans: 1066close_trans:
1075 clnt->trans_mod->close(clnt); 1067 clnt->trans_mod->close(clnt);
1076destroy_fidpool:
1077 p9_idpool_destroy(clnt->fidpool);
1078put_trans: 1068put_trans:
1079 v9fs_put_trans(clnt->trans_mod); 1069 v9fs_put_trans(clnt->trans_mod);
1080destroy_tagpool: 1070destroy_tagpool:
@@ -1087,7 +1077,8 @@ EXPORT_SYMBOL(p9_client_create);
1087 1077
1088void p9_client_destroy(struct p9_client *clnt) 1078void p9_client_destroy(struct p9_client *clnt)
1089{ 1079{
1090 struct p9_fid *fid, *fidptr; 1080 struct p9_fid *fid;
1081 int id;
1091 1082
1092 p9_debug(P9_DEBUG_MUX, "clnt %p\n", clnt); 1083 p9_debug(P9_DEBUG_MUX, "clnt %p\n", clnt);
1093 1084
@@ -1096,14 +1087,11 @@ void p9_client_destroy(struct p9_client *clnt)
1096 1087
1097 v9fs_put_trans(clnt->trans_mod); 1088 v9fs_put_trans(clnt->trans_mod);
1098 1089
1099 list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist) { 1090 idr_for_each_entry(&clnt->fids, fid, id) {
1100 pr_info("Found fid %d not clunked\n", fid->fid); 1091 pr_info("Found fid %d not clunked\n", fid->fid);
1101 p9_fid_destroy(fid); 1092 p9_fid_destroy(fid);
1102 } 1093 }
1103 1094
1104 if (clnt->fidpool)
1105 p9_idpool_destroy(clnt->fidpool);
1106
1107 p9_tag_cleanup(clnt); 1095 p9_tag_cleanup(clnt);
1108 1096
1109 kfree(clnt); 1097 kfree(clnt);