Skip to content

Commit 0b57c5b

Browse files
committed
Add RCU
1 parent ae75e00 commit 0b57c5b

2 files changed

Lines changed: 12 additions & 34 deletions

File tree

include/linux/uswitch.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ struct fs_struct;
1212
struct nsproxy;
1313
struct task_struct;
1414
struct uswitch_context_struct {
15-
atomic_t users;
1615
refcount_t refs;
1716
spinlock_t lock;
1817
struct files_struct *files;

kernel/uswitch.c

Lines changed: 12 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -189,15 +189,14 @@ static int copy_uswitch_thread(struct task_struct *tsk) {
189189
kernel_data->fork_control = USWITCH_FORK_DISABLE;
190190
refcount_inc(&public_table->refs);
191191

192-
spin_lock(&public_table->lock);
192+
rcu_read_lock();
193193
ctx = (struct uswitch_context_struct *)idr_find(&public_table->ctx_idr, current_cid);
194194
if (!ctx) {
195195
ret = -EINVAL;
196-
spin_unlock(&public_table->lock);
196+
rcu_read_unlock();
197197
goto fail_set_ref;
198198
}
199-
atomic_inc(&ctx->users);
200-
spin_unlock(&public_table->lock);
199+
rcu_read_unlock();
201200

202201
down_write(&mm->mmap_lock);
203202
user_addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
@@ -241,12 +240,6 @@ static int copy_uswitch_thread(struct task_struct *tsk) {
241240
vm_area_free(vma);
242241
fail_get_unmap:
243242
up_write(&mm->mmap_lock);
244-
spin_lock(&public_table->lock);
245-
ctx = (struct uswitch_context_struct *)idr_find(&public_table->ctx_idr, current_cid);
246-
if (ctx) {
247-
atomic_dec(&ctx->users);
248-
}
249-
spin_unlock(&public_table->lock);
250243
fail_set_ref:
251244
refcount_dec(&public_table->refs);
252245
fail_malloc:
@@ -287,7 +280,6 @@ static struct uswitch_context_struct *copy_uswitch_ctx(struct uswitch_contexts_t
287280

288281
spin_lock_init(&dst_ctx->lock);
289282
refcount_set(&dst_ctx->refs, 1);
290-
atomic_set(&dst_ctx->users, 0);
291283

292284
spin_lock(&src_ctx->lock);
293285
files = src_ctx->files;
@@ -414,7 +406,6 @@ static int copy_uswitch_fork(struct task_struct *tsk, int fork_control) {
414406
ctx = copy_uswitch_ctx(ptab, public_table, current_cid, &ret);
415407
if (!ctx)
416408
goto fail_copy_ctxs;
417-
atomic_set(&ctx->users, 1);
418409

419410
if (fork_control == USWITCH_FORK_CURRENT_AND_ANOTHER && current_cid != fork_descriptor) {
420411
ctx = copy_uswitch_ctx(ptab, public_table, fork_descriptor, &ret);
@@ -569,7 +560,6 @@ int do_uswitch_init(struct uswitch_data **pdata, int flags)
569560
ctxs->current_cid = 0;
570561
ctxs->data_page = data_page;
571562
ctxs->kernel_data = kernel_data;
572-
atomic_set(&ctx->users, 1);
573563
refcount_set(&ctx->refs, 1);
574564
refcount_set(&public_table->refs, 1);
575565
spin_lock_init(&ctx->lock);
@@ -706,7 +696,6 @@ int do_uswitch_clone(int flags)
706696
}
707697
spin_lock_init(&ctx->lock);
708698
refcount_set(&ctx->refs, 1);
709-
atomic_set(&ctx->users, 0);
710699

711700
if (fd_share || fd_copy) {
712701
files = get_task_files(tsk);
@@ -819,9 +808,9 @@ int do_uswitch_switch(bool *need_switch_seccomp)
819808
ctxs->kernel_data->next_descriptor = -1;
820809
}
821810
if (seccomp_cid != -1 && seccomp_cid != current_cid && need_switch_seccomp) {
822-
spin_lock(&ctxs->public_table->lock);
811+
rcu_read_lock();
823812
seccomp_ctx = get_uswitch_ctx(ctxs->public_table, seccomp_cid);
824-
spin_unlock(&ctxs->public_table->lock);
813+
rcu_read_unlock();
825814
if (!seccomp_ctx)
826815
return -EBUSY;
827816
spin_lock(&seccomp_ctx->lock);
@@ -851,15 +840,12 @@ int do_uswitch_switch(bool *need_switch_seccomp)
851840
return current_cid;
852841
}
853842

854-
spin_lock(&ctxs->public_table->lock);
843+
rcu_read_lock();
855844
current_ctx = get_uswitch_ctx(ctxs->public_table, current_cid);
856845
next_ctx = get_uswitch_ctx(ctxs->public_table, next_cid);
857-
if (next_ctx) {
858-
atomic_inc(&next_ctx->users);
859-
}
860846
if (seccomp_cid != -1 && seccomp_cid != next_cid && need_switch_seccomp)
861847
seccomp_ctx = get_uswitch_ctx(ctxs->public_table, seccomp_cid);
862-
spin_unlock(&ctxs->public_table->lock);
848+
rcu_read_unlock();
863849
//printk("%px %px %d %d %px %px\n", ctxs->kernel_data, ctxs->user_data, current_cid, next_cid, current_ctx, next_ctx);
864850

865851
if (!next_ctx) {
@@ -966,10 +952,8 @@ int do_uswitch_switch(bool *need_switch_seccomp)
966952
ctxs->current_cid = next_cid;
967953
// set user counts
968954

969-
if (current_ctx) {
970-
atomic_dec(&current_ctx->users);
955+
if (current_ctx)
971956
put_uswitch_ctx(current_ctx);
972-
}
973957
put_uswitch_ctx(next_ctx);
974958
put_uswitch_ctx(seccomp_ctx);
975959
return next_cid;
@@ -986,16 +970,11 @@ int do_uswitch_destroy(int cid)
986970
if (ctxs->current_cid == cid)
987971
return -EBUSY;
988972
spin_lock(&ctxs->public_table->lock);
989-
ctx = (struct uswitch_context_struct *)idr_find(&ctxs->public_table->ctx_idr, cid);
973+
ctx = (struct uswitch_context_struct *)idr_remove(&ctxs->public_table->ctx_idr, cid);
990974
if (!ctx) {
991975
ret = -EINVAL;
992976
goto cleanup;
993977
}
994-
if (atomic_read(&ctx->users)) {
995-
ret = -EBUSY;
996-
goto cleanup;
997-
}
998-
idr_remove(&ctxs->public_table->ctx_idr, cid);
999978
spin_unlock(&ctxs->public_table->lock);
1000979
put_uswitch_ctx(ctx);
1001980
return 0;
@@ -1013,14 +992,14 @@ int do_uswitch_dup_file(int cid, unsigned int fd)
1013992
int ret;
1014993
if (!ctxs)
1015994
return -EINVAL;
1016-
spin_lock(&ctxs->public_table->lock);
995+
rcu_read_lock();
1017996
ctx = (struct uswitch_context_struct *)idr_find(&ctxs->public_table->ctx_idr, cid);
1018997
if (!ctx) {
1019-
spin_unlock(&ctxs->public_table->lock);
998+
rcu_read_unlock();
1020999
return -EINVAL;
10211000
}
10221001
file = fget_files(ctx->files, fd);
1023-
spin_unlock(&ctxs->public_table->lock);
1002+
rcu_read_unlock();
10241003
if (!file)
10251004
return -EBADF;
10261005
ret = get_unused_fd_flags(0);

0 commit comments

Comments
 (0)