]> err.no Git - linux-2.6/blobdiff - include/linux/backing-dev.h
mm: bdi: allow setting a maximum for the bdi dirty limit
[linux-2.6] / include / linux / backing-dev.h
index f2542c24b328b291c23b3cbee3a12a9f1ae45e86..ad3271d1e90a4061caf159acbd6e60d3479acd05 100644 (file)
@@ -8,9 +8,14 @@
 #ifndef _LINUX_BACKING_DEV_H
 #define _LINUX_BACKING_DEV_H
 
+#include <linux/percpu_counter.h>
+#include <linux/log2.h>
+#include <linux/proportions.h>
+#include <linux/kernel.h>
 #include <asm/atomic.h>
 
 struct page;
+struct device;
 
 /*
  * Bits in backing_dev_info.state
@@ -24,6 +29,14 @@ enum bdi_state {
 
 typedef int (congested_fn)(void *, int);
 
+enum bdi_stat_item {
+       BDI_RECLAIMABLE,
+       BDI_WRITEBACK,
+       NR_BDI_STAT_ITEMS
+};
+
+#define BDI_STAT_BATCH (8*(1+ilog2(nr_cpu_ids)))
+
 struct backing_dev_info {
        unsigned long ra_pages; /* max readahead in PAGE_CACHE_SIZE units */
        unsigned long state;    /* Always use atomic bitops on this */
@@ -32,8 +45,103 @@ struct backing_dev_info {
        void *congested_data;   /* Pointer to aux data for congested func */
        void (*unplug_io_fn)(struct backing_dev_info *, struct page *);
        void *unplug_io_data;
+
+       struct percpu_counter bdi_stat[NR_BDI_STAT_ITEMS];
+
+       struct prop_local_percpu completions;
+       int dirty_exceeded;
+
+       unsigned int min_ratio;
+       unsigned int max_ratio, max_prop_frac;
+
+       struct device *dev;
 };
 
+int bdi_init(struct backing_dev_info *bdi);
+void bdi_destroy(struct backing_dev_info *bdi);
+
+int bdi_register(struct backing_dev_info *bdi, struct device *parent,
+               const char *fmt, ...);
+int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev);
+void bdi_unregister(struct backing_dev_info *bdi);
+
+static inline void __add_bdi_stat(struct backing_dev_info *bdi,
+               enum bdi_stat_item item, s64 amount)
+{
+       __percpu_counter_add(&bdi->bdi_stat[item], amount, BDI_STAT_BATCH);
+}
+
+static inline void __inc_bdi_stat(struct backing_dev_info *bdi,
+               enum bdi_stat_item item)
+{
+       __add_bdi_stat(bdi, item, 1);
+}
+
+static inline void inc_bdi_stat(struct backing_dev_info *bdi,
+               enum bdi_stat_item item)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       __inc_bdi_stat(bdi, item);
+       local_irq_restore(flags);
+}
+
+static inline void __dec_bdi_stat(struct backing_dev_info *bdi,
+               enum bdi_stat_item item)
+{
+       __add_bdi_stat(bdi, item, -1);
+}
+
+static inline void dec_bdi_stat(struct backing_dev_info *bdi,
+               enum bdi_stat_item item)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       __dec_bdi_stat(bdi, item);
+       local_irq_restore(flags);
+}
+
+static inline s64 bdi_stat(struct backing_dev_info *bdi,
+               enum bdi_stat_item item)
+{
+       return percpu_counter_read_positive(&bdi->bdi_stat[item]);
+}
+
+static inline s64 __bdi_stat_sum(struct backing_dev_info *bdi,
+               enum bdi_stat_item item)
+{
+       return percpu_counter_sum_positive(&bdi->bdi_stat[item]);
+}
+
+static inline s64 bdi_stat_sum(struct backing_dev_info *bdi,
+               enum bdi_stat_item item)
+{
+       s64 sum;
+       unsigned long flags;
+
+       local_irq_save(flags);
+       sum = __bdi_stat_sum(bdi, item);
+       local_irq_restore(flags);
+
+       return sum;
+}
+
+/*
+ * maximal error of a stat counter.
+ */
+static inline unsigned long bdi_stat_error(struct backing_dev_info *bdi)
+{
+#ifdef CONFIG_SMP
+       return nr_cpu_ids * BDI_STAT_BATCH;
+#else
+       return 1;
+#endif
+}
+
+int bdi_set_min_ratio(struct backing_dev_info *bdi, unsigned int min_ratio);
+int bdi_set_max_ratio(struct backing_dev_info *bdi, unsigned int max_ratio);
 
 /*
  * Flags in backing_dev_info::capability
@@ -63,9 +171,7 @@ struct backing_dev_info {
 extern struct backing_dev_info default_backing_dev_info;
 void default_unplug_io_fn(struct backing_dev_info *bdi, struct page *page);
 
-int writeback_acquire(struct backing_dev_info *bdi);
 int writeback_in_progress(struct backing_dev_info *bdi);
-void writeback_release(struct backing_dev_info *bdi);
 
 static inline int bdi_congested(struct backing_dev_info *bdi, int bdi_bits)
 {
@@ -93,8 +199,6 @@ static inline int bdi_rw_congested(struct backing_dev_info *bdi)
 void clear_bdi_congested(struct backing_dev_info *bdi, int rw);
 void set_bdi_congested(struct backing_dev_info *bdi, int rw);
 long congestion_wait(int rw, long timeout);
-long congestion_wait_interruptible(int rw, long timeout);
-void congestion_end(int rw);
 
 #define bdi_cap_writeback_dirty(bdi) \
        (!((bdi)->capabilities & BDI_CAP_NO_WRITEBACK))