]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/2.6.38.8/ext4-use-schedule_timeout_interruptible-for-waiting-in.patch
Fixes for 4.19
[thirdparty/kernel/stable-queue.git] / releases / 2.6.38.8 / ext4-use-schedule_timeout_interruptible-for-waiting-in.patch
1 From 4ed5c033c11b33149d993734a6a8de1016e8f03f Mon Sep 17 00:00:00 2001
2 From: Lukas Czerner <lczerner@redhat.com>
3 Date: Fri, 20 May 2011 13:49:04 -0400
4 Subject: ext4: Use schedule_timeout_interruptible() for waiting in
5 lazyinit thread
6
7 From: Lukas Czerner <lczerner@redhat.com>
8
9 commit 4ed5c033c11b33149d993734a6a8de1016e8f03f upstream.
10
11 In order to make lazyinit eat approx. 10% of io bandwidth at max, we
12 are sleeping between zeroing each single inode table. For that purpose
13 we are using timer which wakes up thread when it expires. It is set
14 via add_timer() and this may cause troubles in the case that thread
15 has been woken up earlier and in next iteration we call add_timer() on
16 still running timer hence hitting BUG_ON in add_timer(). We could fix
17 that by using mod_timer() instead however we can use
18 schedule_timeout_interruptible() for waiting and hence simplifying
19 things a lot.
20
21 This commit exchange the old "waiting mechanism" with simple
22 schedule_timeout_interruptible(), setting the time to sleep. Hence we
23 do not longer need li_wait_daemon waiting queue and others, so get rid
24 of it.
25
26 Addresses-Red-Hat-Bugzilla: #699708
27
28 Signed-off-by: Lukas Czerner <lczerner@redhat.com>
29 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
30 Reviewed-by: Eric Sandeen <sandeen@redhat.com>
31 Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
32
33 ---
34 fs/ext4/ext4.h | 4 ----
35 fs/ext4/super.c | 31 ++++++-------------------------
36 2 files changed, 6 insertions(+), 29 deletions(-)
37
38 --- a/fs/ext4/ext4.h
39 +++ b/fs/ext4/ext4.h
40 @@ -1590,12 +1590,8 @@ void ext4_get_group_no_and_offset(struct
41 */
42 struct ext4_lazy_init {
43 unsigned long li_state;
44 -
45 - wait_queue_head_t li_wait_daemon;
46 wait_queue_head_t li_wait_task;
47 - struct timer_list li_timer;
48 struct task_struct *li_task;
49 -
50 struct list_head li_request_list;
51 struct mutex li_list_mtx;
52 };
53 --- a/fs/ext4/super.c
54 +++ b/fs/ext4/super.c
55 @@ -2645,12 +2645,6 @@ static void print_daily_error_info(unsig
56 mod_timer(&sbi->s_err_report, jiffies + 24*60*60*HZ); /* Once a day */
57 }
58
59 -static void ext4_lazyinode_timeout(unsigned long data)
60 -{
61 - struct task_struct *p = (struct task_struct *)data;
62 - wake_up_process(p);
63 -}
64 -
65 /* Find next suitable group and run ext4_init_inode_table */
66 static int ext4_run_li_request(struct ext4_li_request *elr)
67 {
68 @@ -2698,7 +2692,7 @@ static int ext4_run_li_request(struct ex
69
70 /*
71 * Remove lr_request from the list_request and free the
72 - * request tructure. Should be called with li_list_mtx held
73 + * request structure. Should be called with li_list_mtx held
74 */
75 static void ext4_remove_li_request(struct ext4_li_request *elr)
76 {
77 @@ -2744,14 +2738,10 @@ static int ext4_lazyinit_thread(void *ar
78 struct ext4_lazy_init *eli = (struct ext4_lazy_init *)arg;
79 struct list_head *pos, *n;
80 struct ext4_li_request *elr;
81 - unsigned long next_wakeup;
82 - DEFINE_WAIT(wait);
83 + unsigned long next_wakeup, cur;
84
85 BUG_ON(NULL == eli);
86
87 - eli->li_timer.data = (unsigned long)current;
88 - eli->li_timer.function = ext4_lazyinode_timeout;
89 -
90 eli->li_task = current;
91 wake_up(&eli->li_wait_task);
92
93 @@ -2785,19 +2775,15 @@ cont_thread:
94 if (freezing(current))
95 refrigerator();
96
97 - if ((time_after_eq(jiffies, next_wakeup)) ||
98 + cur = jiffies;
99 + if ((time_after_eq(cur, next_wakeup)) ||
100 (MAX_JIFFY_OFFSET == next_wakeup)) {
101 cond_resched();
102 continue;
103 }
104
105 - eli->li_timer.expires = next_wakeup;
106 - add_timer(&eli->li_timer);
107 - prepare_to_wait(&eli->li_wait_daemon, &wait,
108 - TASK_INTERRUPTIBLE);
109 - if (time_before(jiffies, next_wakeup))
110 - schedule();
111 - finish_wait(&eli->li_wait_daemon, &wait);
112 + schedule_timeout_interruptible(next_wakeup - cur);
113 +
114 if (kthread_should_stop()) {
115 ext4_clear_request_list();
116 goto exit_thread;
117 @@ -2821,12 +2807,10 @@ exit_thread:
118 goto cont_thread;
119 }
120 mutex_unlock(&eli->li_list_mtx);
121 - del_timer_sync(&ext4_li_info->li_timer);
122 eli->li_task = NULL;
123 wake_up(&eli->li_wait_task);
124
125 kfree(ext4_li_info);
126 - ext4_lazyinit_task = NULL;
127 ext4_li_info = NULL;
128 mutex_unlock(&ext4_li_mtx);
129
130 @@ -2854,7 +2838,6 @@ static int ext4_run_lazyinit_thread(void
131 if (IS_ERR(ext4_lazyinit_task)) {
132 int err = PTR_ERR(ext4_lazyinit_task);
133 ext4_clear_request_list();
134 - del_timer_sync(&ext4_li_info->li_timer);
135 kfree(ext4_li_info);
136 ext4_li_info = NULL;
137 printk(KERN_CRIT "EXT4: error %d creating inode table "
138 @@ -2903,9 +2886,7 @@ static int ext4_li_info_new(void)
139 INIT_LIST_HEAD(&eli->li_request_list);
140 mutex_init(&eli->li_list_mtx);
141
142 - init_waitqueue_head(&eli->li_wait_daemon);
143 init_waitqueue_head(&eli->li_wait_task);
144 - init_timer(&eli->li_timer);
145 eli->li_state |= EXT4_LAZYINIT_QUIT;
146
147 ext4_li_info = eli;