diff options
author | David S. Miller <davem@davemloft.net> | 2008-07-18 02:39:39 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-07-18 02:39:39 -0700 |
commit | 49997d75152b3d23c53b0fa730599f2f74c92c65 (patch) | |
tree | 46e93126170d02cfec9505172e545732c1b69656 /drivers/video/fb_defio.c | |
parent | a0c80b80e0fb48129e4e9d6a9ede914f9ff1850d (diff) | |
parent | 5b664cb235e97afbf34db9c4d77f08ebd725335e (diff) | |
download | op-kernel-dev-49997d75152b3d23c53b0fa730599f2f74c92c65.zip op-kernel-dev-49997d75152b3d23c53b0fa730599f2f74c92c65.tar.gz |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
Documentation/powerpc/booting-without-of.txt
drivers/atm/Makefile
drivers/net/fs_enet/fs_enet-main.c
drivers/pci/pci-acpi.c
net/8021q/vlan.c
net/iucv/iucv.c
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 24843fd..59df132 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 */ |