diff options
-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 24843fdd5395..59df132cc375 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, | |||
74 | { | 74 | { |
75 | struct fb_info *info = vma->vm_private_data; | 75 | struct fb_info *info = vma->vm_private_data; |
76 | struct fb_deferred_io *fbdefio = info->fbdefio; | 76 | struct fb_deferred_io *fbdefio = info->fbdefio; |
77 | struct page *cur; | ||
77 | 78 | ||
78 | /* this is a callback we get when userspace first tries to | 79 | /* this is a callback we get when userspace first tries to |
79 | write to the page. we schedule a workqueue. that workqueue | 80 | 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, | |||
83 | 84 | ||
84 | /* protect against the workqueue changing the page list */ | 85 | /* protect against the workqueue changing the page list */ |
85 | mutex_lock(&fbdefio->lock); | 86 | mutex_lock(&fbdefio->lock); |
86 | list_add(&page->lru, &fbdefio->pagelist); | 87 | |
88 | /* we loop through the pagelist before adding in order | ||
89 | to keep the pagelist sorted */ | ||
90 | list_for_each_entry(cur, &fbdefio->pagelist, lru) { | ||
91 | /* this check is to catch the case where a new | ||
92 | process could start writing to the same page | ||
93 | through a new pte. this new access can cause the | ||
94 | mkwrite even when the original ps's pte is marked | ||
95 | writable */ | ||
96 | if (unlikely(cur == page)) | ||
97 | goto page_already_added; | ||
98 | else if (cur->index > page->index) | ||
99 | break; | ||
100 | } | ||
101 | |||
102 | list_add_tail(&page->lru, &cur->lru); | ||
103 | |||
104 | page_already_added: | ||
87 | mutex_unlock(&fbdefio->lock); | 105 | mutex_unlock(&fbdefio->lock); |
88 | 106 | ||
89 | /* come back after delay to process the deferred IO */ | 107 | /* come back after delay to process the deferred IO */ |