diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 604a3414082f0a7cf2ee76a5bc7369a7f9c395f2..dd406043469ac6e2febe0b5138473bb3dc354e90 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -188,6 +188,14 @@ nfsd(struct svc_rqst *rqstp) list_add(&me.list, &nfsd_list); unlock_kernel(); + + /* + * We want less throttling in balance_dirty_pages() so that nfs to + * localhost doesn't cause nfsd to lock up due to all the client's + * dirty pages. + */ + current->flags |= PF_LESS_THROTTLE; + /* * The main request loop */ diff --git a/include/linux/sched.h b/include/linux/sched.h index b7a364022625ea3d6cb7c3dd4483a327f60ab4f8..d313e2ccbf424ef874488c8db58c65ddaddc1248 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -475,6 +475,7 @@ do { if (atomic_dec_and_test(&(tsk)->usage)) __put_task_struct(tsk); } while(0) #define PF_FSTRANS 0x00020000 /* inside a filesystem transaction */ #define PF_KSWAPD 0x00040000 /* I am kswapd */ #define PF_SWAPOFF 0x00080000 /* I am in swapoff */ +#define PF_LESS_THROTTLE 0x01000000 /* Throttle me less: I clena memory */ #ifdef CONFIG_SMP extern void set_cpus_allowed(task_t *p, unsigned long new_mask); diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 27ddc1244ce934f9e8930b6d1ad935381aa562a9..9e54d17adaaa7245f5fc4b69484fc2176c382f3d 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -104,11 +104,13 @@ static void background_writeout(unsigned long _min_pages); * clamping level. */ static void -get_dirty_limits(struct page_state *ps, long *background, long *dirty) +get_dirty_limits(struct page_state *ps, long *pbackground, long *pdirty) { int background_ratio; /* Percentages */ int dirty_ratio; int unmapped_ratio; + long background; + long dirty; get_page_state(ps); @@ -125,8 +127,14 @@ get_dirty_limits(struct page_state *ps, long *background, long *dirty) if (background_ratio >= dirty_ratio) background_ratio = dirty_ratio / 2; - *background = (background_ratio * total_pages) / 100; - *dirty = (dirty_ratio * total_pages) / 100; + background = (background_ratio * total_pages) / 100; + dirty = (dirty_ratio * total_pages) / 100; + if (current->flags & PF_LESS_THROTTLE) { + background += background / 4; + dirty += dirty / 4; + } + *pbackground = background; + *pdirty = dirty; } /*