Operating Systems
Just another WordPress.com weblog

Linux patch

Linux patch for bdi flusher tasks

Suspend resume in Linux exposed yet another problem. I should say two problems. One very deep the other one not quite.

First the easy problem:

If a task is already in the refrigerator and we want to stop the task, it simply won’t. This is because of the design of the refrigerator.

Here is the code at the heart of the refrigerator!
for (;;) {
set_current_state(TASK_UNINTERRUPTIBLE);
if (!frozen(current))
break;
schedule();
}

what it means is if the task is frozen and it is woken up, it will be scheduled out until we have PF_FROZEN flag cleared out of the task flags in which case frozen(current) will be FALSE.

The MMC suspend routine assumes that the block device is removable and on suspend tries to delete the block device. Eventually it will attempt to kill the bdi thread backing the block device. But by now (when the suspend routine is called) the bdi thread is in the refrigerator. This results in the suspend thread being blocked for ever. Here is the patch that solves the problem:

Kicks out frozen bdi flusher task out of the refrigerator when the flusher task
needs to exit.
Signed-off-by: Romit Dasgupta <romit@ti.com>
---
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index 5a37e20..c757b05 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -606,8 +606,11 @@ static void bdi_wb_shutdown(struct backing_dev_info *bdi)
 	 * Finally, kill the kernel threads. We don't need to be RCU
 	 * safe anymore, since the bdi is gone from visibility.
 	 */
-	list_for_each_entry(wb, &bdi->wb_list, list)
+	list_for_each_entry(wb, &bdi->wb_list, list) {
+		if (unlikely(frozen(wb->task)))
+			wb->task->flags &= ~PF_FROZEN;
 		kthread_stop(wb->task);
+	}
 }

One Response to “Linux patch”

  1. Hi, this is a comment.
    To delete a comment, just log in, and view the posts’ comments, there you will have the option to edit or delete them.


Leave a comment