diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/fb_defio.c | 40 |
1 files changed, 8 insertions, 32 deletions
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c index 073c9b4..137100e 100644 --- a/drivers/video/fb_defio.c +++ b/drivers/video/fb_defio.c @@ -155,41 +155,25 @@ static void fb_deferred_io_work(struct work_struct *work) { struct fb_info *info = container_of(work, struct fb_info, deferred_work.work); + struct list_head *node, *next; + struct page *cur; struct fb_deferred_io *fbdefio = info->fbdefio; - struct page *page, *tmp_page; - struct list_head *node, *tmp_node; - struct list_head non_dirty; - - INIT_LIST_HEAD(&non_dirty); /* here we mkclean the pages, then do all deferred IO */ mutex_lock(&fbdefio->lock); - list_for_each_entry_safe(page, tmp_page, &fbdefio->pagelist, lru) { - lock_page(page); - /* - * The workqueue callback can be triggered after a - * ->page_mkwrite() call but before the PTE has been marked - * dirty. In this case page_mkclean() won't "rearm" the page. - * - * To avoid this, remove those "non-dirty" pages from the - * pagelist before calling the driver's callback, then add - * them back to get processed on the next work iteration. - * At that time, their PTEs will hopefully be dirty for real. - */ - if (!page_mkclean(page)) - list_move_tail(&page->lru, &non_dirty); - unlock_page(page); + list_for_each_entry(cur, &fbdefio->pagelist, lru) { + lock_page(cur); + page_mkclean(cur); + unlock_page(cur); } /* driver's callback with pagelist */ fbdefio->deferred_io(info, &fbdefio->pagelist); - /* clear the list... */ - list_for_each_safe(node, tmp_node, &fbdefio->pagelist) { + /* clear the list */ + list_for_each_safe(node, next, &fbdefio->pagelist) { list_del(node); } - /* ... and add back the "non-dirty" pages to the list */ - list_splice_tail(&non_dirty, &fbdefio->pagelist); mutex_unlock(&fbdefio->lock); } @@ -218,7 +202,6 @@ EXPORT_SYMBOL_GPL(fb_deferred_io_open); void fb_deferred_io_cleanup(struct fb_info *info) { struct fb_deferred_io *fbdefio = info->fbdefio; - struct list_head *node, *tmp_node; struct page *page; int i; @@ -226,13 +209,6 @@ void fb_deferred_io_cleanup(struct fb_info *info) cancel_delayed_work(&info->deferred_work); flush_scheduled_work(); - /* the list may have still some non-dirty pages at this point */ - mutex_lock(&fbdefio->lock); - list_for_each_safe(node, tmp_node, &fbdefio->pagelist) { - list_del(node); - } - mutex_unlock(&fbdefio->lock); - /* clear out the mapping that we setup */ for (i = 0 ; i < info->fix.smem_len; i += PAGE_SIZE) { page = fb_deferred_io_page(info, i); |