diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-07-14 11:37:46 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-14 11:37:46 +0200 |
commit | d59fdcf2ac501de99c3dfb452af5e254d4342886 (patch) | |
tree | ad5e2efd6f8aacf2a08b1ed8a54ddf96642e83f3 /drivers/video/fb_defio.c | |
parent | 2387ce57a8167490d3b34a7e1ffa9a64a1a76244 (diff) | |
parent | bce7f793daec3e65ec5c5705d2457b81fe7b5725 (diff) |
Merge commit 'v2.6.26' into x86/core
Diffstat (limited to 'drivers/video/fb_defio.c')
-rw-r--r-- | drivers/video/fb_defio.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c index 24843fdd539..59df132cc37 100644 --- a/drivers/video/fb_defio.c +++ b/drivers/video/fb_defio.c @@ -74,6 +74,7 @@ static int fb_deferred_io_mkwrite(struct vm_area_struct *vma, { struct fb_info *info = vma->vm_private_data; struct fb_deferred_io *fbdefio = info->fbdefio; + struct page *cur; /* this is a callback we get when userspace first tries to write to the page. we schedule a workqueue. that workqueue @@ -83,7 +84,24 @@ static int fb_deferred_io_mkwrite(struct vm_area_struct *vma, /* protect against the workqueue changing the page list */ mutex_lock(&fbdefio->lock); - list_add(&page->lru, &fbdefio->pagelist); + + /* we loop through the pagelist before adding in order + to keep the pagelist sorted */ + list_for_each_entry(cur, &fbdefio->pagelist, lru) { + /* this check is to catch the case where a new + process could start writing to the same page + through a new pte. this new access can cause the + mkwrite even when the original ps's pte is marked + writable */ + if (unlikely(cur == page)) + goto page_already_added; + else if (cur->index > page->index) + break; + } + + list_add_tail(&page->lru, &cur->lru); + +page_already_added: mutex_unlock(&fbdefio->lock); /* come back after delay to process the deferred IO */ |