diff options
| -rw-r--r-- | drivers/video/fb_defio.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c index 137100ea8ad7..6b93ef93cb12 100644 --- a/drivers/video/fb_defio.c +++ b/drivers/video/fb_defio.c | |||
| @@ -100,6 +100,16 @@ static int fb_deferred_io_mkwrite(struct vm_area_struct *vma, | |||
| 100 | /* protect against the workqueue changing the page list */ | 100 | /* protect against the workqueue changing the page list */ |
| 101 | mutex_lock(&fbdefio->lock); | 101 | mutex_lock(&fbdefio->lock); |
| 102 | 102 | ||
| 103 | /* | ||
| 104 | * We want the page to remain locked from ->page_mkwrite until | ||
| 105 | * the PTE is marked dirty to avoid page_mkclean() being called | ||
| 106 | * before the PTE is updated, which would leave the page ignored | ||
| 107 | * by defio. | ||
| 108 | * Do this by locking the page here and informing the caller | ||
| 109 | * about it with VM_FAULT_LOCKED. | ||
| 110 | */ | ||
| 111 | lock_page(page); | ||
| 112 | |||
| 103 | /* we loop through the pagelist before adding in order | 113 | /* we loop through the pagelist before adding in order |
| 104 | to keep the pagelist sorted */ | 114 | to keep the pagelist sorted */ |
| 105 | list_for_each_entry(cur, &fbdefio->pagelist, lru) { | 115 | list_for_each_entry(cur, &fbdefio->pagelist, lru) { |
| @@ -121,7 +131,7 @@ page_already_added: | |||
| 121 | 131 | ||
| 122 | /* come back after delay to process the deferred IO */ | 132 | /* come back after delay to process the deferred IO */ |
| 123 | schedule_delayed_work(&info->deferred_work, fbdefio->delay); | 133 | schedule_delayed_work(&info->deferred_work, fbdefio->delay); |
| 124 | return 0; | 134 | return VM_FAULT_LOCKED; |
| 125 | } | 135 | } |
| 126 | 136 | ||
| 127 | static const struct vm_operations_struct fb_deferred_io_vm_ops = { | 137 | static const struct vm_operations_struct fb_deferred_io_vm_ops = { |
