fuse: suspend blockers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

We are seeing a number of cases when blocked fuse requests prevent
the system from suspending, which is a little important on laptops.
Usually something like this:

[ 36.281038] Freezing user space processes
[ 56.284961] Freezing user space processes failed after 20.003 seconds (1 tasks refusing to freeze, wq_busy=0):
[ 56.285069] task:secagentd state:D stack:0 pid:1792 ppid:1711 flags:0x00004006
[ 56.285084] Call Trace:
[ 56.285091] <TASK>
[ 56.285111] schedule+0x612/0x2230
[ 56.285136] fuse_get_req+0x108/0x2d0
[ 56.285179] fuse_simple_request+0x40/0x630
[ 56.285203] fuse_getxattr+0x15d/0x1c0
[...]

Which looks like wait_event_killable_exclusive() in fuse_get_req().
And we were wondering if we could do something about it.  For example,
perhaps, something like:

---

diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index f182a4ca1bb32..587cea3a0407d 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -241,7 +241,7 @@ static struct fuse_req *fuse_get_req(struct fuse_conn *fc, bool for_background)
 
        if (fuse_block_alloc(fc, for_background)) {
                err = -EINTR;
-               if (wait_event_killable_exclusive(fc->blocked_waitq,
+               if (wait_event_freezable_killable_exclusive(fc->blocked_waitq,
                                !fuse_block_alloc(fc, for_background)))
                        goto out;
        }
diff --git a/include/linux/wait.h b/include/linux/wait.h
index 5b65f720261a9..1c8fdf1e02785 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -628,6 +628,19 @@ do {                                                                               \
        __ret;                                                                  \
 })
 
+#define __wait_event_freezable_killable_exclusive(wq, condition)               \
+       ___wait_event(wq, condition, TASK_KILLABLE, 1, 0,                       \
+                     freezable_schedule())
+
+#define wait_event_freezable_killable_exclusive(wq, condition)                 \
+({                                                                             \
+       int __ret = 0;                                                          \
+       might_sleep();                                                          \
+       if (!(condition))                                                       \
+               __ret = __wait_event_freezable_killable_exclusive(wq,           \
+                                                                 condition);   \
+       __ret;                                                                  \
+})
 
 #define __wait_event_freezable_exclusive(wq, condition)                                \
        ___wait_event(wq, condition, TASK_INTERRUPTIBLE, 1, 0,                  \

---

Would this be a terrible idea?




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux