From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ian Campbell Subject: [PATCH] gnttab: propagate Reserved flag from old to new page in gnttab_copy_grant_page. Date: Tue, 23 Feb 2010 16:40:18 +0000 Message-ID: <1266943218-16666-1-git-send-email-ian.campbell@citrix.com> References: <1266943189.11737.6457.camel@zakaz.uk.xensource.com> Return-path: In-Reply-To: <1266943189.11737.6457.camel@zakaz.uk.xensource.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: xen-devel@lists.xensource.com Cc: Jeremy Fitzhardinge , Ian Campbell List-Id: xen-devel@lists.xenproject.org Otherwise we trip over the check for PAGE_FLAGS_CHECK_AT_FREE in free_pages_check() when finally freeing the page, leading to backtraces such as: Bad page state in process 'tcpdump' page:c15b8ae0 flags:0x40000800 mapping:00000000 mapcount:0 count:0 Trying to fix it up, but a reboot is needed Backtrace: Pid: 5731, comm: tcpdump Tainted: G 2.6.27.42-0.1.1.xs5.5.900.751.1073xen #1 [] bad_page+0x6b/0xa0 [] free_hot_cold_page+0x239/0x250 [] free_hot_page+0xa/0x10 [] put_page+0x35/0xc0 [] gnttab_page_free+0x22/0x30 [] free_hot_cold_page+0x1d5/0x250 [] free_hot_page+0xa/0x10 [] put_page+0x35/0xc0 [] skb_put_page+0xa/0x10 [] skb_release_data+0x77/0x90 [] skb_release_all+0x6b/0xa0 [] __kfree_skb+0xb/0x80 [] kfree_skb+0x1e/0x40 [] skb_free_datagram+0xd/0x40 [] packet_recvmsg+0x186/0x1c0 [] ? __rmqueue+0x1b/0x1a0 [] sock_recvmsg+0x102/0x130 [] ? autoremove_wake_function+0x0/0x50 [] ? __do_fault+0x2e7/0x5f0 [] ? sockfd_lookup_light+0x30/0x60 [] sys_recvfrom+0x7d/0xe0 [] ? __kmalloc+0x139/0x190 [] ? copy_from_user+0x3c/0x70 [] ? _spin_lock_bh+0x14/0x70 [] ? _spin_unlock_bh+0x23/0x30 [] ? release_sock+0x9f/0xc0 [] sys_recv+0x36/0x40 [] sys_socketcall+0x15f/0x290 [] syscall_call+0x7/0xb [] ? pci_scan_bus_on_node+0x10/0x80 ======================= gnttab_copy_grant_page is (currently) only ever used on pages which were allocated by alloc_empty_pages_and_pagevec() and hence have the PG_reserved set. Also free_empty_pages_and_pagevec() can BUG_ON(!PageReserved(page)). Signed-off-by: Ian Campbell --- drivers/xen/grant-table.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index 17efd09..7079787 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c @@ -558,9 +558,12 @@ int gnttab_copy_grant_page(grant_ref_t ref, struct page **pagep) new_page->mapping = page->mapping; new_page->index = page->index; set_bit(PG_foreign, &new_page->flags); + if (PageReserved(page)) + set_bit(PG_reserved, &new_page->flags); *pagep = new_page; SetPageForeign(page, gnttab_page_free); + ClearPageReserved(page); page->mapping = NULL; out: -- 1.5.6.5