linux/fs/jffs2/background.c
<<
>>
Prefs
   1/*
   2 * JFFS2 -- Journalling Flash File System, Version 2.
   3 *
   4 * Copyright © 2001-2007 Red Hat, Inc.
   5 * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
   6 *
   7 * Created by David Woodhouse <dwmw2@infradead.org>
   8 *
   9 * For licensing information, see the file 'LICENCE' in this directory.
  10 *
  11 */
  12
  13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  14
  15#include <linux/kernel.h>
  16#include <linux/jffs2.h>
  17#include <linux/mtd/mtd.h>
  18#include <linux/completion.h>
  19#include <linux/sched.h>
  20#include <linux/freezer.h>
  21#include <linux/kthread.h>
  22#include "nodelist.h"
  23
  24
  25static int jffs2_garbage_collect_thread(void *);
  26
  27void jffs2_garbage_collect_trigger(struct jffs2_sb_info *c)
  28{
  29        assert_spin_locked(&c->erase_completion_lock);
  30        if (c->gc_task && jffs2_thread_should_wake(c))
  31                send_sig(SIGHUP, c->gc_task, 1);
  32}
  33
  34/* This must only ever be called when no GC thread is currently running */
  35int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c)
  36{
  37        struct task_struct *tsk;
  38        int ret = 0;
  39
  40        BUG_ON(c->gc_task);
  41
  42        init_completion(&c->gc_thread_start);
  43        init_completion(&c->gc_thread_exit);
  44
  45        tsk = kthread_run(jffs2_garbage_collect_thread, c, "jffs2_gcd_mtd%d", c->mtd->index);
  46        if (IS_ERR(tsk)) {
  47                pr_warn("fork failed for JFFS2 garbage collect thread: %ld\n",
  48                        -PTR_ERR(tsk));
  49                complete(&c->gc_thread_exit);
  50                ret = PTR_ERR(tsk);
  51        } else {
  52                /* Wait for it... */
  53                jffs2_dbg(1, "Garbage collect thread is pid %d\n", tsk->pid);
  54                wait_for_completion(&c->gc_thread_start);
  55                ret = tsk->pid;
  56        }
  57
  58        return ret;
  59}
  60
  61void jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c)
  62{
  63        int wait = 0;
  64        spin_lock(&c->erase_completion_lock);
  65        if (c->gc_task) {
  66                jffs2_dbg(1, "Killing GC task %d\n", c->gc_task->pid);
  67                send_sig(SIGKILL, c->gc_task, 1);
  68                wait = 1;
  69        }
  70        spin_unlock(&c->erase_completion_lock);
  71        if (wait)
  72                wait_for_completion(&c->gc_thread_exit);
  73}
  74
  75static int jffs2_garbage_collect_thread(void *_c)
  76{
  77        struct jffs2_sb_info *c = _c;
  78        sigset_t hupmask;
  79
  80        siginitset(&hupmask, sigmask(SIGHUP));
  81        allow_signal(SIGKILL);
  82        allow_signal(SIGSTOP);
  83        allow_signal(SIGCONT);
  84        allow_signal(SIGHUP);
  85
  86        c->gc_task = current;
  87        complete(&c->gc_thread_start);
  88
  89        set_user_nice(current, 10);
  90
  91        set_freezable();
  92        for (;;) {
  93                sigprocmask(SIG_UNBLOCK, &hupmask, NULL);
  94        again:
  95                spin_lock(&c->erase_completion_lock);
  96                if (!jffs2_thread_should_wake(c)) {
  97                        set_current_state (TASK_INTERRUPTIBLE);
  98                        spin_unlock(&c->erase_completion_lock);
  99                        jffs2_dbg(1, "%s(): sleeping...\n", __func__);
 100                        schedule();
 101                } else {
 102                        spin_unlock(&c->erase_completion_lock);
 103                }
 104                /* Problem - immediately after bootup, the GCD spends a lot
 105                 * of time in places like jffs2_kill_fragtree(); so much so
 106                 * that userspace processes (like gdm and X) are starved
 107                 * despite plenty of cond_resched()s and renicing.  Yield()
 108                 * doesn't help, either (presumably because userspace and GCD
 109                 * are generally competing for a higher latency resource -
 110                 * disk).
 111                 * This forces the GCD to slow the hell down.   Pulling an
 112                 * inode in with read_inode() is much preferable to having
 113                 * the GC thread get there first. */
 114                schedule_timeout_interruptible(msecs_to_jiffies(50));
 115
 116                if (kthread_should_stop()) {
 117                        jffs2_dbg(1, "%s(): kthread_stop() called\n", __func__);
 118                        goto die;
 119                }
 120
 121                /* Put_super will send a SIGKILL and then wait on the sem.
 122                 */
 123                while (signal_pending(current) || freezing(current)) {
 124                        siginfo_t info;
 125                        unsigned long signr;
 126
 127                        if (try_to_freeze())
 128                                goto again;
 129
 130                        signr = dequeue_signal_lock(current, &current->blocked, &info);
 131
 132                        switch(signr) {
 133                        case SIGSTOP:
 134                                jffs2_dbg(1, "%s(): SIGSTOP received\n",
 135                                          __func__);
 136                                set_current_state(TASK_STOPPED);
 137                                schedule();
 138                                break;
 139
 140                        case SIGKILL:
 141                                jffs2_dbg(1, "%s(): SIGKILL received\n",
 142                                          __func__);
 143                                goto die;
 144
 145                        case SIGHUP:
 146                                jffs2_dbg(1, "%s(): SIGHUP received\n",
 147                                          __func__);
 148                                break;
 149                        default:
 150                                jffs2_dbg(1, "%s(): signal %ld received\n",
 151                                          __func__, signr);
 152                        }
 153                }
 154                /* We don't want SIGHUP to interrupt us. STOP and KILL are OK though. */
 155                sigprocmask(SIG_BLOCK, &hupmask, NULL);
 156
 157                jffs2_dbg(1, "%s(): pass\n", __func__);
 158                if (jffs2_garbage_collect_pass(c) == -ENOSPC) {
 159                        pr_notice("No space for garbage collection. Aborting GC thread\n");
 160                        goto die;
 161                }
 162        }
 163 die:
 164        spin_lock(&c->erase_completion_lock);
 165        c->gc_task = NULL;
 166        spin_unlock(&c->erase_completion_lock);
 167        complete_and_exit(&c->gc_thread_exit, 0);
 168}
 169