linux/mm/backing-dev.c
<<
>>
Prefs
   1
   2#include <linux/wait.h>
   3#include <linux/backing-dev.h>
   4#include <linux/fs.h>
   5#include <linux/sched.h>
   6#include <linux/module.h>
   7
   8int bdi_init(struct backing_dev_info *bdi)
   9{
  10        int i;
  11        int err;
  12
  13        for (i = 0; i < NR_BDI_STAT_ITEMS; i++) {
  14                err = percpu_counter_init_irq(&bdi->bdi_stat[i], 0);
  15                if (err)
  16                        goto err;
  17        }
  18
  19        bdi->dirty_exceeded = 0;
  20        err = prop_local_init_percpu(&bdi->completions);
  21
  22        if (err) {
  23err:
  24                while (i--)
  25                        percpu_counter_destroy(&bdi->bdi_stat[i]);
  26        }
  27
  28        return err;
  29}
  30EXPORT_SYMBOL(bdi_init);
  31
  32void bdi_destroy(struct backing_dev_info *bdi)
  33{
  34        int i;
  35
  36        for (i = 0; i < NR_BDI_STAT_ITEMS; i++)
  37                percpu_counter_destroy(&bdi->bdi_stat[i]);
  38
  39        prop_local_destroy_percpu(&bdi->completions);
  40}
  41EXPORT_SYMBOL(bdi_destroy);
  42
  43static wait_queue_head_t congestion_wqh[2] = {
  44                __WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[0]),
  45                __WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[1])
  46        };
  47
  48
  49void clear_bdi_congested(struct backing_dev_info *bdi, int rw)
  50{
  51        enum bdi_state bit;
  52        wait_queue_head_t *wqh = &congestion_wqh[rw];
  53
  54        bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested;
  55        clear_bit(bit, &bdi->state);
  56        smp_mb__after_clear_bit();
  57        if (waitqueue_active(wqh))
  58                wake_up(wqh);
  59}
  60EXPORT_SYMBOL(clear_bdi_congested);
  61
  62void set_bdi_congested(struct backing_dev_info *bdi, int rw)
  63{
  64        enum bdi_state bit;
  65
  66        bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested;
  67        set_bit(bit, &bdi->state);
  68}
  69EXPORT_SYMBOL(set_bdi_congested);
  70
  71/**
  72 * congestion_wait - wait for a backing_dev to become uncongested
  73 * @rw: READ or WRITE
  74 * @timeout: timeout in jiffies
  75 *
  76 * Waits for up to @timeout jiffies for a backing_dev (any backing_dev) to exit
  77 * write congestion.  If no backing_devs are congested then just wait for the
  78 * next write to be completed.
  79 */
  80long congestion_wait(int rw, long timeout)
  81{
  82        long ret;
  83        DEFINE_WAIT(wait);
  84        wait_queue_head_t *wqh = &congestion_wqh[rw];
  85
  86        prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);
  87        ret = io_schedule_timeout(timeout);
  88        finish_wait(wqh, &wait);
  89        return ret;
  90}
  91EXPORT_SYMBOL(congestion_wait);
  92
  93