diff options
author | Matthew Wilcox <willy@infradead.org> | 2018-07-11 17:02:22 -0400 |
---|---|---|
committer | Dominique Martinet <dominique.martinet@cea.fr> | 2018-08-12 20:21:44 -0400 |
commit | f28cdf0430fc92acaa718e15598bdad6cb236a4d (patch) | |
tree | 26c62e06986d2a7a46680c272b2db065cda9a38c | |
parent | b5303be2bee3c8b29de3f7f4ea8ae00c4e816760 (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.h | 9 | ||||
-rw-r--r-- | net/9p/client.c | 44 |
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 | ||
935 | error: | ||
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 | ||
1074 | close_trans: | 1066 | close_trans: |
1075 | clnt->trans_mod->close(clnt); | 1067 | clnt->trans_mod->close(clnt); |
1076 | destroy_fidpool: | ||
1077 | p9_idpool_destroy(clnt->fidpool); | ||
1078 | put_trans: | 1068 | put_trans: |
1079 | v9fs_put_trans(clnt->trans_mod); | 1069 | v9fs_put_trans(clnt->trans_mod); |
1080 | destroy_tagpool: | 1070 | destroy_tagpool: |
@@ -1087,7 +1077,8 @@ EXPORT_SYMBOL(p9_client_create); | |||
1087 | 1077 | ||
1088 | void p9_client_destroy(struct p9_client *clnt) | 1078 | void 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); |