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
7 From: Lukas Czerner <lczerner@redhat.com>
9 commit 4ed5c033c11b33149d993734a6a8de1016e8f03f upstream.
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
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
26 Addresses-Red-Hat-Bugzilla: #699708
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>
34 fs/ext4/ext4.h | 4 ----
35 fs/ext4/super.c | 31 ++++++-------------------------
36 2 files changed, 6 insertions(+), 29 deletions(-)
40 @@ -1590,12 +1590,8 @@ void ext4_get_group_no_and_offset(struct
42 struct ext4_lazy_init {
43 unsigned long li_state;
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;
50 struct list_head li_request_list;
51 struct mutex li_list_mtx;
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 */
59 -static void ext4_lazyinode_timeout(unsigned long data)
61 - struct task_struct *p = (struct task_struct *)data;
65 /* Find next suitable group and run ext4_init_inode_table */
66 static int ext4_run_li_request(struct ext4_li_request *elr)
68 @@ -2698,7 +2692,7 @@ static int ext4_run_li_request(struct ex
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
75 static void ext4_remove_li_request(struct ext4_li_request *elr)
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;
83 + unsigned long next_wakeup, cur;
87 - eli->li_timer.data = (unsigned long)current;
88 - eli->li_timer.function = ext4_lazyinode_timeout;
90 eli->li_task = current;
91 wake_up(&eli->li_wait_task);
93 @@ -2785,19 +2775,15 @@ cont_thread:
94 if (freezing(current))
97 - if ((time_after_eq(jiffies, next_wakeup)) ||
99 + if ((time_after_eq(cur, next_wakeup)) ||
100 (MAX_JIFFY_OFFSET == next_wakeup)) {
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))
111 - finish_wait(&eli->li_wait_daemon, &wait);
112 + schedule_timeout_interruptible(next_wakeup - cur);
114 if (kthread_should_stop()) {
115 ext4_clear_request_list();
117 @@ -2821,12 +2807,10 @@ exit_thread:
120 mutex_unlock(&eli->li_list_mtx);
121 - del_timer_sync(&ext4_li_info->li_timer);
123 wake_up(&eli->li_wait_task);
126 - ext4_lazyinit_task = NULL;
128 mutex_unlock(&ext4_li_mtx);
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);
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);
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;