--- orig/drivers/block/ll_rw_blk.c 2003-04-02 12:34:23.000000000 -0700 +++ linux-2.4.20/drivers/block/ll_rw_blk.c 2003-04-02 12:34:23.000000000 -0700 @@ -1207,6 +1207,7 @@ kstat.pgpgin += count; break; } + conditional_schedule(); } /** --- orig/fs/buffer.c 2003-04-02 12:34:23.000000000 -0700 +++ linux-2.4.20/fs/buffer.c 2003-04-02 12:34:23.000000000 -0700 @@ -255,12 +255,19 @@ struct buffer_head * next; int nr; - next = lru_list[index]; nr = nr_buffers_type[index]; +repeat: + next = lru_list[index]; while (next && --nr >= 0) { struct buffer_head *bh = next; next = bh->b_next_free; + if (dev == NODEV && current->need_resched) { + spin_unlock(&lru_list_lock); + conditional_schedule(); + spin_lock(&lru_list_lock); + goto repeat; + } if (!buffer_locked(bh)) { if (refile) __refile_buffer(bh); @@ -1117,8 +1124,10 @@ struct buffer_head * bh; bh = getblk(dev, block, size); - if (buffer_uptodate(bh)) + if (buffer_uptodate(bh)) { + conditional_schedule(); return bh; + } ll_rw_block(READ, 1, &bh); wait_on_buffer(bh); if (buffer_uptodate(bh)) --- orig/fs/dcache.c 2003-04-02 12:34:23.000000000 -0700 +++ linux-2.4.20/fs/dcache.c 2003-04-02 12:34:23.000000000 -0700 @@ -71,7 +71,7 @@ * d_iput() operation if defined. * Called with dcache_lock held, drops it. */ -static inline void dentry_iput(struct dentry * dentry) +static void dentry_iput(struct dentry * dentry) { struct inode *inode = dentry->d_inode; if (inode) { @@ -84,6 +84,7 @@ iput(inode); } else spin_unlock(&dcache_lock); + conditional_schedule(); } /* --- orig/fs/jbd/commit.c 2003-04-02 12:34:23.000000000 -0700 +++ linux-2.4.20/fs/jbd/commit.c 2003-04-02 12:34:23.000000000 -0700 @@ -212,6 +212,16 @@ __journal_remove_journal_head(bh); refile_buffer(bh); __brelse(bh); + if (current->need_resched) { + if (commit_transaction->t_sync_datalist) + commit_transaction->t_sync_datalist = + next_jh; + if (bufs) + break; + spin_unlock(&journal_datalist_lock); + conditional_schedule(); + goto write_out_data; + } } } if (bufs == ARRAY_SIZE(wbuf)) { --- orig/fs/proc/array.c 2003-04-02 12:34:23.000000000 -0700 +++ linux-2.4.20/fs/proc/array.c 2003-04-02 12:34:23.000000000 -0700 @@ -418,6 +418,8 @@ pte_t page = *pte; struct page *ptpage; + conditional_schedule(); + address += PAGE_SIZE; pte++; if (pte_none(page)) --- orig/fs/proc/generic.c 2003-04-02 12:34:23.000000000 -0700 +++ linux-2.4.20/fs/proc/generic.c 2003-04-02 12:34:23.000000000 -0700 @@ -98,7 +98,9 @@ retval = n; break; } - + + conditional_schedule(); + /* This is a hack to allow mangling of file pos independent * of actual bytes read. Simply place the data at page, * return the bytes, and set `start' to the desired offset --- orig/include/linux/condsched.h 2003-04-02 12:34:23.000000000 -0700 +++ linux-2.4.20/include/linux/condsched.h 2003-04-02 12:34:23.000000000 -0700 @@ -0,0 +1,18 @@ +#ifndef _LINUX_CONDSCHED_H +#define _LINUX_CONDSCHED_H + +#ifndef __LINUX_COMPILER_H +#include +#endif + +#ifndef __ASSEMBLY__ +#define conditional_schedule() \ +do { \ + if (unlikely(current->need_resched)) { \ + __set_current_state(TASK_RUNNING); \ + schedule(); \ + } \ +} while(0) +#endif + +#endif --- orig/include/linux/sched.h 2003-04-02 12:34:23.000000000 -0700 +++ linux-2.4.20/include/linux/sched.h 2003-04-02 12:34:23.000000000 -0700 @@ -13,6 +13,7 @@ #include #include #include +#include #include #include --- orig/mm/filemap.c 2003-04-02 12:34:23.000000000 -0700 +++ linux-2.4.20/mm/filemap.c 2003-04-02 12:34:23.000000000 -0700 @@ -302,10 +302,7 @@ page_cache_release(page); - if (current->need_resched) { - __set_current_state(TASK_RUNNING); - schedule(); - } + conditional_schedule(); spin_lock(&pagecache_lock); goto restart; @@ -584,6 +581,7 @@ UnlockPage(page); page_cache_release(page); + conditional_schedule(); spin_lock(&pagecache_lock); } spin_unlock(&pagecache_lock); @@ -1450,6 +1448,9 @@ offset &= ~PAGE_CACHE_MASK; page_cache_release(page); + + conditional_schedule(); + if (ret == nr && desc->count) continue; break; @@ -3138,6 +3139,8 @@ UnlockPage(page); page_cache_release(page); + conditional_schedule(); + if (status < 0) break; } while (count);