]> git.hungrycats.org Git - linux/commitdiff
[PATCH] pdflush cleanup
authorAndrew Morton <akpm@zip.com.au>
Thu, 4 Jul 2002 15:30:34 +0000 (08:30 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Thu, 4 Jul 2002 15:30:34 +0000 (08:30 -0700)
Writeback/pdflush cleanup patch from Steven Augart

* Exposes nr_pdflush_threads as /proc/sys/vm/nr_pdflush_threads, read-only.

  (I like this - I expect that management of the pdflush thread pool
  will be important for many-spindle machines, and this is a neat way
  of getting at the info).

* Adds minimum and maximum checking to the five writable pdflush
  and fs-writeback  parameters.

* Minor indentation fix in sysctl.c

* mm/pdflush.c now includes linux/writeback.h, which prototypes
  pdflush_operation.  This is so that the compiler can
  automatically check that the prototype matches the definition.

* Adds a few comments to existing code.

include/linux/sysctl.h
include/linux/writeback.h
kernel/sysctl.c
mm/page-writeback.c
mm/pdflush.c

index 488bc05dbcc1bc37d4285e65edd51ce520dda4a4..da8115ec58f6bb5df067becbb1a2003d13f0e5f8 100644 (file)
 
 struct file;
 
-#define CTL_MAXNAME 10
+#define CTL_MAXNAME 10         /* how many path components do we allow in a
+                                  call to sysctl?   In other words, what is
+                                  the largest acceptable value for the nlen
+                                  member of a struct __sysctl_args to have? */
 
 struct __sysctl_args {
        int *name;
@@ -145,6 +148,7 @@ enum
        VM_DIRTY_SYNC=13,       /* dirty_sync_ratio */
        VM_DIRTY_WB_CS=14,      /* dirty_writeback_centisecs */
        VM_DIRTY_EXPIRE_CS=15,  /* dirty_expire_centisecs */
+       VM_NR_PDFLUSH_THREADS=16, /* nr_pdflush_threads */
 };
 
 
index 1b2034aa56178b7669a2a9207410048cab3bde18..af3ec94cb2adbaf71701ddf24ec5c9b30d81182e 100644 (file)
@@ -49,15 +49,22 @@ static inline void wait_on_inode(struct inode *inode)
 /*
  * mm/page-writeback.c
  */
+/* These 5 are exported to sysctl. */
 extern int dirty_background_ratio;
 extern int dirty_async_ratio;
 extern int dirty_sync_ratio;
 extern int dirty_writeback_centisecs;
 extern int dirty_expire_centisecs;
 
+
 void balance_dirty_pages(struct address_space *mapping);
 void balance_dirty_pages_ratelimited(struct address_space *mapping);
 int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0);
 int do_writepages(struct address_space *mapping, int *nr_to_write);
 
+/* pdflush.c */
+extern int nr_pdflush_threads; /* Global so it can be exported to sysctl
+                                  read-only. */
+
+
 #endif         /* WRITEBACK_H */
index f0c6215b17183b0d5562e5554e903dbf2f605182..0c2c938efb65c557afa5e98f449d9e4d739c1b33 100644 (file)
@@ -258,6 +258,13 @@ static ctl_table kern_table[] = {
        {0}
 };
 
+/* Constants for minimum and maximum testing in vm_table.
+   We use these as one-element integer vectors. */
+static int zero = 0;
+static int one = 1;
+static int one_hundred = 100;
+
+
 static ctl_table vm_table[] = {
        {VM_OVERCOMMIT_MEMORY, "overcommit_memory", &sysctl_overcommit_memory,
         sizeof(sysctl_overcommit_memory), 0644, NULL, &proc_dointvec},
@@ -266,18 +273,37 @@ static ctl_table vm_table[] = {
        {VM_PAGE_CLUSTER, "page-cluster", 
         &page_cluster, sizeof(int), 0644, NULL, &proc_dointvec},
        {VM_DIRTY_BACKGROUND, "dirty_background_ratio",
-       &dirty_background_ratio, sizeof(dirty_background_ratio),
-       0644, NULL, &proc_dointvec},
+        &dirty_background_ratio, sizeof(dirty_background_ratio),
+        0644, NULL, &proc_dointvec_minmax,  &sysctl_intvec, NULL,
+        &zero, &one_hundred },
        {VM_DIRTY_ASYNC, "dirty_async_ratio", &dirty_async_ratio,
-       sizeof(dirty_async_ratio), 0644, NULL, &proc_dointvec},
+        sizeof(dirty_async_ratio), 0644, NULL, &proc_dointvec_minmax,
+        &sysctl_intvec, NULL, &zero, &one_hundred },
        {VM_DIRTY_SYNC, "dirty_sync_ratio", &dirty_sync_ratio,
-       sizeof(dirty_sync_ratio), 0644, NULL, &proc_dointvec},
+        sizeof(dirty_sync_ratio), 0644, NULL, &proc_dointvec_minmax,
+        &sysctl_intvec, NULL, &zero, &one_hundred },
        {VM_DIRTY_WB_CS, "dirty_writeback_centisecs",
-       &dirty_writeback_centisecs, sizeof(dirty_writeback_centisecs), 0644,
-       NULL, &proc_dointvec},
+        &dirty_writeback_centisecs, sizeof(dirty_writeback_centisecs), 0644,
+        NULL, &proc_dointvec_minmax, &sysctl_intvec, NULL,
+        /* Here, we define the range of possible values for
+           dirty_writeback_centisecs.
+
+           The default value is 5 seconds (500 centisec).  We will use 1
+           centisec, the smallest possible value that could make any sort of
+           sense.  If we allowed the user to set the interval to 0 seconds
+           (which would presumably mean to chew up all of the CPU looking for
+           dirty pages and writing them out, without taking a break), the
+           interval would effectively become 1 second (100 centisecs), due to
+           some nicely documented throttling code in wb_kupdate().
+
+           There is no maximum legal value for dirty_writeback. */
+        &one , NULL},
        {VM_DIRTY_EXPIRE_CS, "dirty_expire_centisecs",
-       &dirty_expire_centisecs, sizeof(dirty_expire_centisecs), 0644,
-       NULL, &proc_dointvec},
+        &dirty_expire_centisecs, sizeof(dirty_expire_centisecs), 0644,
+        NULL, &proc_dointvec},
+       { VM_NR_PDFLUSH_THREADS, "nr_pdflush_threads",
+         &nr_pdflush_threads, sizeof nr_pdflush_threads,
+         0444 /* read-only*/, NULL, &proc_dointvec},
        {0}
 };
 
index 6d4555c3fb91347d63439c27f5bd59d57286c9ff..18a8af187ccbd1b1c5abccfce86e08eaf0f7d5e0 100644 (file)
@@ -47,6 +47,8 @@
 #define SYNC_WRITEBACK_PAGES   1500
 
 
+/* The following parameters are exported via /proc/sys/vm */
+
 /*
  * Dirty memory thresholds, in percentages
  */
@@ -67,15 +69,18 @@ int dirty_async_ratio = 50;
 int dirty_sync_ratio = 60;
 
 /*
- * The interval between `kupdate'-style writebacks.
+ * The interval between `kupdate'-style writebacks, in centiseconds
+ * (hundredths of a second)
  */
 int dirty_writeback_centisecs = 5 * 100;
 
 /*
- * The largest amount of time for which data is allowed to remain dirty
+ * The longest amount of time for which data is allowed to remain dirty
  */
 int dirty_expire_centisecs = 30 * 100;
 
+/* End of sysctl-exported parameters */
+
 
 static void background_writeout(unsigned long _min_pages);
 
@@ -233,7 +238,8 @@ static void wb_kupdate(unsigned long arg)
 static void wb_timer_fn(unsigned long unused)
 {
        if (pdflush_operation(wb_kupdate, 0) < 0)
-               mod_timer(&wb_timer, jiffies + HZ);
+               mod_timer(&wb_timer, jiffies + HZ); /* delay 1 second */
+
 }
 
 static int __init wb_timer_init(void)
index 16aa09b697fdca8537e8db73bcac792c75e2e948..26fef9bc32356c5dc16dcccfcbbf8e652414150f 100644 (file)
@@ -15,6 +15,9 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/suspend.h>
+#include <linux/sched.h>       // Needed by writeback.h
+#include <linux/fs.h>          // Needed by writeback.h
+#include <linux/writeback.h>   // Prototypes pdflush_operation()
 
 
 /*
@@ -44,8 +47,11 @@ static spinlock_t pdflush_lock = SPIN_LOCK_UNLOCKED;
 /*
  * The count of currently-running pdflush threads.  Protected
  * by pdflush_lock.
+ *
+ * Readable by sysctl, but not writable.  Published to userspace at
+ * /proc/sys/vm/nr_pdflush_threads.
  */
-static int nr_pdflush_threads = 0;
+int nr_pdflush_threads = 0;
 
 /*
  * The time at which the pdflush thread pool last went empty