]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/blob - rt-patches/0144-fs-aio-simple-simple-work.patch
Fix memguard and related syscalls
[hercules2020/nv-tegra/linux-4.4.git] / rt-patches / 0144-fs-aio-simple-simple-work.patch
1 From a97cf69051f51c5a544e95abcf12553119050f14 Mon Sep 17 00:00:00 2001
2 From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
3 Date: Mon, 16 Feb 2015 18:49:10 +0100
4 Subject: [PATCH 144/366] fs/aio: simple simple work
5
6 |BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:768
7 |in_atomic(): 1, irqs_disabled(): 0, pid: 26, name: rcuos/2
8 |2 locks held by rcuos/2/26:
9 | #0:  (rcu_callback){.+.+..}, at: [<ffffffff810b1a12>] rcu_nocb_kthread+0x1e2/0x380
10 | #1:  (rcu_read_lock_sched){.+.+..}, at: [<ffffffff812acd26>] percpu_ref_kill_rcu+0xa6/0x1c0
11 |Preemption disabled at:[<ffffffff810b1a93>] rcu_nocb_kthread+0x263/0x380
12 |Call Trace:
13 | [<ffffffff81582e9e>] dump_stack+0x4e/0x9c
14 | [<ffffffff81077aeb>] __might_sleep+0xfb/0x170
15 | [<ffffffff81589304>] rt_spin_lock+0x24/0x70
16 | [<ffffffff811c5790>] free_ioctx_users+0x30/0x130
17 | [<ffffffff812ace34>] percpu_ref_kill_rcu+0x1b4/0x1c0
18 | [<ffffffff810b1a93>] rcu_nocb_kthread+0x263/0x380
19 | [<ffffffff8106e046>] kthread+0xd6/0xf0
20 | [<ffffffff81591eec>] ret_from_fork+0x7c/0xb0
21
22 replace this preempt_disable() friendly swork.
23
24 Reported-By: Mike Galbraith <umgwanakikbuti@gmail.com>
25 Suggested-by: Benjamin LaHaise <bcrl@kvack.org>
26 Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
27 ---
28  fs/aio.c | 24 +++++++++++++++++-------
29  1 file changed, 17 insertions(+), 7 deletions(-)
30
31 diff --git a/fs/aio.c b/fs/aio.c
32 index fe4f492..a879f87 100644
33 --- a/fs/aio.c
34 +++ b/fs/aio.c
35 @@ -40,6 +40,7 @@
36  #include <linux/ramfs.h>
37  #include <linux/percpu-refcount.h>
38  #include <linux/mount.h>
39 +#include <linux/work-simple.h>
40  
41  #include <asm/kmap_types.h>
42  #include <asm/uaccess.h>
43 @@ -115,7 +116,7 @@ struct kioctx {
44         struct page             **ring_pages;
45         long                    nr_pages;
46  
47 -       struct work_struct      free_work;
48 +       struct swork_event      free_work;
49  
50         /*
51          * signals when all in-flight requests are done
52 @@ -258,6 +259,7 @@ static int __init aio_setup(void)
53                 .mount          = aio_mount,
54                 .kill_sb        = kill_anon_super,
55         };
56 +       BUG_ON(swork_get());
57         aio_mnt = kern_mount(&aio_fs);
58         if (IS_ERR(aio_mnt))
59                 panic("Failed to create aio fs mount.");
60 @@ -573,9 +575,9 @@ static int kiocb_cancel(struct aio_kiocb *kiocb)
61         return cancel(&kiocb->common);
62  }
63  
64 -static void free_ioctx(struct work_struct *work)
65 +static void free_ioctx(struct swork_event *sev)
66  {
67 -       struct kioctx *ctx = container_of(work, struct kioctx, free_work);
68 +       struct kioctx *ctx = container_of(sev, struct kioctx, free_work);
69  
70         pr_debug("freeing %p\n", ctx);
71  
72 @@ -594,8 +596,8 @@ static void free_ioctx_reqs(struct percpu_ref *ref)
73         if (ctx->rq_wait && atomic_dec_and_test(&ctx->rq_wait->count))
74                 complete(&ctx->rq_wait->comp);
75  
76 -       INIT_WORK(&ctx->free_work, free_ioctx);
77 -       schedule_work(&ctx->free_work);
78 +       INIT_SWORK(&ctx->free_work, free_ioctx);
79 +       swork_queue(&ctx->free_work);
80  }
81  
82  /*
83 @@ -603,9 +605,9 @@ static void free_ioctx_reqs(struct percpu_ref *ref)
84   * and ctx->users has dropped to 0, so we know no more kiocbs can be submitted -
85   * now it's safe to cancel any that need to be.
86   */
87 -static void free_ioctx_users(struct percpu_ref *ref)
88 +static void free_ioctx_users_work(struct swork_event *sev)
89  {
90 -       struct kioctx *ctx = container_of(ref, struct kioctx, users);
91 +       struct kioctx *ctx = container_of(sev, struct kioctx, free_work);
92         struct aio_kiocb *req;
93  
94         spin_lock_irq(&ctx->ctx_lock);
95 @@ -624,6 +626,14 @@ static void free_ioctx_users(struct percpu_ref *ref)
96         percpu_ref_put(&ctx->reqs);
97  }
98  
99 +static void free_ioctx_users(struct percpu_ref *ref)
100 +{
101 +       struct kioctx *ctx = container_of(ref, struct kioctx, users);
102 +
103 +       INIT_SWORK(&ctx->free_work, free_ioctx_users_work);
104 +       swork_queue(&ctx->free_work);
105 +}
106 +
107  static int ioctx_add_table(struct kioctx *ctx, struct mm_struct *mm)
108  {
109         unsigned i, new_nr;
110 -- 
111 1.9.1
112