Messages in this thread Patches in this message | | | Date | Wed, 28 Apr 1999 22:31:54 +0200 (CEST) | From | Andrea Arcangeli <> | Subject | [patch] run_task_queue(&tq_disk) overhead in __wait_on_xxx |
| |
I think the implementation of wait_on_page() and wait_on_buffer() are not too much friendly with the I/O subsystem. The problem is that such two functions does a run_task_queue() even if after the wakeup the page was just unlocked. So they are probably going to do I/O too early even if not needed.
Index: fs/buffer.c =================================================================== RCS file: /var/cvs/linux/fs/buffer.c,v retrieving revision 1.1.1.8 diff -u -r1.1.1.8 buffer.c --- linux/fs/buffer.c 1999/03/29 21:38:51 1.1.1.8 +++ linux/fs/buffer.c 1999/04/28 20:09:41 @@ -134,13 +134,13 @@ bh->b_count++; wait.task = tsk; add_wait_queue(&bh->b_wait, &wait); -repeat: - tsk->state = TASK_UNINTERRUPTIBLE; - run_task_queue(&tq_disk); - if (buffer_locked(bh)) { + do { + tsk->state = TASK_UNINTERRUPTIBLE; + run_task_queue(&tq_disk); + if (!buffer_locked(bh)) + break; schedule(); - goto repeat; - } + } while (buffer_locked(bh)); tsk->state = TASK_RUNNING; remove_wait_queue(&bh->b_wait, &wait); bh->b_count--; Index: mm/filemap.c =================================================================== RCS file: /var/cvs/linux/mm/filemap.c,v retrieving revision 1.1.1.8 diff -u -r1.1.1.8 filemap.c --- linux/mm/filemap.c 1999/03/24 00:53:22 1.1.1.8 +++ linux/mm/filemap.c 1999/04/28 20:08:23 @@ -310,13 +310,13 @@ wait.task = tsk; add_wait_queue(&page->wait, &wait); -repeat: - tsk->state = TASK_UNINTERRUPTIBLE; - run_task_queue(&tq_disk); - if (PageLocked(page)) { + do { + tsk->state = TASK_UNINTERRUPTIBLE; + run_task_queue(&tq_disk); + if (!PageLocked(page)) + break; schedule(); - goto repeat; - } + } while (PageLocked(page)); tsk->state = TASK_RUNNING; remove_wait_queue(&page->wait, &wait); }
It would be interesting to know if this patch does any performance difference in real world... the patch make sense to me thoguh, so I am posting it. This second patch instead fix a subtle race I seen some month ago in the swap code, the problem was that we was running a sleep_on but the wakeup is going to happen in a irq handler beween the test and the sleep_on).
Index: mm/page_io.c =================================================================== RCS file: /var/cvs/linux/mm/page_io.c,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 page_io.c --- linux/mm/page_io.c 1999/01/18 01:27:01 1.1.1.1 +++ linux/mm/page_io.c 1999/04/28 20:15:17 @@ -86,9 +86,22 @@ if (PageSwapCache(page)) { /* Make sure we are the only process doing I/O with this swap page. */ - while (test_and_set_bit(offset,p->swap_lockmap)) { - run_task_queue(&tq_disk); - sleep_on(&lock_queue); + if (test_and_set_bit(offset,p->swap_lockmap)) + { + struct task_struct *tsk = current; + struct wait_queue wait; + + wait.task = tsk; + add_wait_queue(&lock_queue, &wait); + do { + tsk->state = TASK_UNINTERRUPTIBLE; + run_task_queue(&tq_disk); + if (!test_and_set_bit(offset, p->swap_lockmap)) + break; + schedule(); + } while (test_and_set_bit(offset, p->swap_lockmap)); + tsk->state = TASK_RUNNING; + remove_wait_queue(&lock_queue, &wait); } /*
Andrea Arcangeli
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |