Linux Headquarters
[ Register ]
[ About us ] [ Home Page ]

Advertisement
[ Kernel ] [ Documentation ] [ Links ] [ Books ]

Advertisement

Kernel v2.6.25-git19 /mm/page-writeback.c

Filename:/mm/page-writeback.c
Lines Added:71
Lines Deleted:6
Also changed in: (Previous) 2.6.25-git18  2.6.25-git17  2.6.25-git16  2.6.25  2.6.25-rc9  2.6.25-rc8 
(Following) 2.6.25-git20  2.6.26-rc1  2.6.26-rc2  2.6.26-rc3  2.6.26-rc4  2.6.26-rc5 

Location
[  2.6.25-git19
  [  mm
     o  page-writeback.c

Patch

diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 5e00f17..789b6ad 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -164,9 +164,20 @@ int dirty_ratio_handler(struct ctl_table *table, int write,
  */
 static inline void __bdi_writeout_inc(struct backing_dev_info *bdi)
 {
-   __prop_inc_percpu(&vm_completions, &bdi->completions);
+   __prop_inc_percpu_max(&vm_completions, &bdi->completions,
+               bdi->max_prop_frac);
 }
 
+void bdi_writeout_inc(struct backing_dev_info *bdi)
+{
+   unsigned long flags;
+
+   local_irq_save(flags);
+   __bdi_writeout_inc(bdi);
+   local_irq_restore(flags);
+}
+EXPORT_SYMBOL_GPL(bdi_writeout_inc);
+
 static inline void task_dirty_inc(struct task_struct *tsk)
 {
    prop_inc_single(&vm_dirties, &tsk->dirties);
@@ -200,7 +211,8 @@ clip_bdi_dirty_limit(struct backing_dev_info *bdi, long dirty, long *pbdi_dirty)
    avail_dirty = dirty -
       (global_page_state(NR_FILE_DIRTY) +
        global_page_state(NR_WRITEBACK) +
-       global_page_state(NR_UNSTABLE_NFS));
+       global_page_state(NR_UNSTABLE_NFS) +
+       global_page_state(NR_WRITEBACK_TEMP));
 
    if (avail_dirty < 0)
       avail_dirty = 0;
@@ -243,6 +255,55 @@ static void task_dirty_limit(struct task_struct *tsk, long *pdirty)
 }
 
 /*
+ *
+ */
+static DEFINE_SPINLOCK(bdi_lock);
+static unsigned int bdi_min_ratio;
+
+int bdi_set_min_ratio(struct backing_dev_info *bdi, unsigned int min_ratio)
+{
+   int ret = 0;
+   unsigned long flags;
+
+   spin_lock_irqsave(&bdi_lock, flags);
+   if (min_ratio > bdi->max_ratio) {
+      ret = -EINVAL;
+   } else {
+      min_ratio -= bdi->min_ratio;
+      if (bdi_min_ratio + min_ratio < 100) {
+         bdi_min_ratio += min_ratio;
+         bdi->min_ratio += min_ratio;
+      } else {
+         ret = -EINVAL;
+      }
+   }
+   spin_unlock_irqrestore(&bdi_lock, flags);
+
+   return ret;
+}
+
+int bdi_set_max_ratio(struct backing_dev_info *bdi, unsigned max_ratio)
+{
+   unsigned long flags;
+   int ret = 0;
+
+   if (max_ratio > 100)
+      return -EINVAL;
+
+   spin_lock_irqsave(&bdi_lock, flags);
+   if (bdi->min_ratio > max_ratio) {
+      ret = -EINVAL;
+   } else {
+      bdi->max_ratio = max_ratio;
+      bdi->max_prop_frac = (PROP_FRAC_BASE * max_ratio) / 100;
+   }
+   spin_unlock_irqrestore(&bdi_lock, flags);
+
+   return ret;
+}
+EXPORT_SYMBOL(bdi_set_max_ratio);
+
+/*
  * Work out the current dirty-memory clamping and background writeout
  * thresholds.
  *
@@ -300,7 +361,7 @@ static unsigned long determine_dirtyable_memory(void)
    return x + 1;   /* Ensure that we never return 0 */
 }
 
-static void
+void
 get_dirty_limits(long *pbackground, long *pdirty, long *pbdi_dirty,
        struct backing_dev_info *bdi)
 {
@@ -330,7 +391,7 @@ get_dirty_limits(long *pbackground, long *pdirty, long *pbdi_dirty,
    *pdirty = dirty;
 
    if (bdi) {
-      u64 bdi_dirty = dirty;
+      u64 bdi_dirty;
       long numerator, denominator;
 
       /*
@@ -338,8 +399,12 @@ get_dirty_limits(long *pbackground, long *pdirty, long *pbdi_dirty,
        */
       bdi_writeout_fraction(bdi, &numerator, &denominator);
 
+      bdi_dirty = (dirty * (100 - bdi_min_ratio)) / 100;
       bdi_dirty *= numerator;
       do_div(bdi_dirty, denominator);
+      bdi_dirty += (dirty * bdi->min_ratio) / 100;
+      if (bdi_dirty > (dirty * bdi->max_ratio) / 100)
+         bdi_dirty = dirty * bdi->max_ratio / 100;
 
       *pbdi_dirty = bdi_dirty;
       clip_bdi_dirty_limit(bdi, dirty, pbdi_dirty);
@@ -1192,7 +1257,7 @@ int test_clear_page_writeback(struct page *page)
          radix_tree_tag_clear(&mapping->page_tree,
                   page_index(page),
                   PAGECACHE_TAG_WRITEBACK);
-         if (bdi_cap_writeback_dirty(bdi)) {
+         if (bdi_cap_account_writeback(bdi)) {
             __dec_bdi_stat(bdi, BDI_WRITEBACK);
             __bdi_writeout_inc(bdi);
          }
@@ -1221,7 +1286,7 @@ int test_set_page_writeback(struct page *page)
          radix_tree_tag_set(&mapping->page_tree,
                   page_index(page),
                   PAGECACHE_TAG_WRITEBACK);
-         if (bdi_cap_writeback_dirty(bdi))
+         if (bdi_cap_account_writeback(bdi))
             __inc_bdi_stat(bdi, BDI_WRITEBACK);
       }
       if (!PageDirty(page))


Comments: webmaster (at) linuxhq.com.
Advertising: banners (at) linuxhq.com.
Compilation ©1998-2008 Linux Headquarters, Inc.