From: Ingo Molnar This patch adds a handful of cond_resched() points to a number of key, scheduling-latency related non-inlined functions. This reduces preemption latency for !PREEMPT kernels. These are scheduling points complementary to PREEMPT_VOLUNTARY scheduling points (might_sleep() places) - i.e. these are all points where an explicit cond_resched() had to be added. Has been tested as part of the -VP patchset. Signed-off-by: Ingo Molnar Signed-off-by: Andrew Morton --- 25-akpm/fs/exec.c | 1 + 25-akpm/fs/fs-writeback.c | 1 + 25-akpm/fs/select.c | 1 + 25-akpm/kernel/printk.c | 3 +++ 25-akpm/mm/memory.c | 1 + 25-akpm/mm/slab.c | 2 +- 25-akpm/mm/vmscan.c | 3 +++ 7 files changed, 11 insertions(+), 1 deletion(-) diff -puN fs/exec.c~sched-fix-scheduling-latencies-for-preempt-kernels fs/exec.c --- 25/fs/exec.c~sched-fix-scheduling-latencies-for-preempt-kernels 2004-11-18 23:47:55.411246928 -0800 +++ 25-akpm/fs/exec.c 2004-11-18 23:47:55.424244952 -0800 @@ -185,6 +185,7 @@ static int count(char __user * __user * argv++; if(++i > max) return -E2BIG; + cond_resched(); } } return i; diff -puN fs/fs-writeback.c~sched-fix-scheduling-latencies-for-preempt-kernels fs/fs-writeback.c --- 25/fs/fs-writeback.c~sched-fix-scheduling-latencies-for-preempt-kernels 2004-11-18 23:47:55.412246776 -0800 +++ 25-akpm/fs/fs-writeback.c 2004-11-18 23:47:55.425244800 -0800 @@ -378,6 +378,7 @@ sync_sb_inodes(struct super_block *sb, s list_move(&inode->i_list, &sb->s_dirty); } spin_unlock(&inode_lock); + cond_resched(); iput(inode); spin_lock(&inode_lock); if (wbc->nr_to_write <= 0) diff -puN fs/select.c~sched-fix-scheduling-latencies-for-preempt-kernels fs/select.c --- 25/fs/select.c~sched-fix-scheduling-latencies-for-preempt-kernels 2004-11-18 23:47:55.414246472 -0800 +++ 25-akpm/fs/select.c 2004-11-18 23:47:55.425244800 -0800 @@ -240,6 +240,7 @@ int do_select(int n, fd_set_bits *fds, l retval++; } } + cond_resched(); } if (res_in) *rinp = res_in; diff -puN kernel/printk.c~sched-fix-scheduling-latencies-for-preempt-kernels kernel/printk.c --- 25/kernel/printk.c~sched-fix-scheduling-latencies-for-preempt-kernels 2004-11-18 23:47:55.415246320 -0800 +++ 25-akpm/kernel/printk.c 2004-11-18 23:47:55.426244648 -0800 @@ -284,6 +284,7 @@ int do_syslog(int type, char __user * bu error = __put_user(c,buf); buf++; i++; + cond_resched(); spin_lock_irq(&logbuf_lock); } spin_unlock_irq(&logbuf_lock); @@ -325,6 +326,7 @@ int do_syslog(int type, char __user * bu c = LOG_BUF(j); spin_unlock_irq(&logbuf_lock); error = __put_user(c,&buf[count-1-i]); + cond_resched(); spin_lock_irq(&logbuf_lock); } spin_unlock_irq(&logbuf_lock); @@ -340,6 +342,7 @@ int do_syslog(int type, char __user * bu error = -EFAULT; break; } + cond_resched(); } } break; diff -puN mm/memory.c~sched-fix-scheduling-latencies-for-preempt-kernels mm/memory.c --- 25/mm/memory.c~sched-fix-scheduling-latencies-for-preempt-kernels 2004-11-18 23:47:55.417246016 -0800 +++ 25-akpm/mm/memory.c 2004-11-18 23:47:55.428244344 -0800 @@ -1740,6 +1740,7 @@ do_no_page(struct mm_struct *mm, struct } smp_rmb(); /* Prevent CPU from reordering lock-free ->nopage() */ retry: + cond_resched(); new_page = vma->vm_ops->nopage(vma, address & PAGE_MASK, &ret); /* no page was available -- either SIGBUS or OOM */ diff -puN mm/slab.c~sched-fix-scheduling-latencies-for-preempt-kernels mm/slab.c --- 25/mm/slab.c~sched-fix-scheduling-latencies-for-preempt-kernels 2004-11-18 23:47:55.419245712 -0800 +++ 25-akpm/mm/slab.c 2004-11-18 23:47:55.430244040 -0800 @@ -2805,7 +2805,7 @@ static void cache_reap(void *unused) next_unlock: spin_unlock_irq(&searchp->spinlock); next: - ; + cond_resched(); } check_irq_on(); up(&cache_chain_sem); diff -puN mm/vmscan.c~sched-fix-scheduling-latencies-for-preempt-kernels mm/vmscan.c --- 25/mm/vmscan.c~sched-fix-scheduling-latencies-for-preempt-kernels 2004-11-18 23:47:55.420245560 -0800 +++ 25-akpm/mm/vmscan.c 2004-11-18 23:47:55.431243888 -0800 @@ -361,6 +361,8 @@ static int shrink_list(struct list_head int may_enter_fs; int referenced; + cond_resched(); + page = lru_to_page(page_list); list_del(&page->lru); @@ -710,6 +712,7 @@ refill_inactive_zone(struct zone *zone, reclaim_mapped = 1; while (!list_empty(&l_hold)) { + cond_resched(); page = lru_to_page(&l_hold); list_del(&page->lru); if (page_mapped(page)) { _