How about this patch? blktap2: add tlb flush properly.
xen_invlpg() flushes tlb on its cpu, but tlb flush is needed on all cpus. So replace xen_invlpg() with more proper ones. Maybe it would be possible to make tlb flush less. this patch also makes blktap2 compile on ia64 because xen_invlpg() is x86 specific. Signed-off-by: Isaku Yamahata <yamah...@valinux.co.jp> diff --git a/drivers/xen/blktap2/device.c b/drivers/xen/blktap2/device.c --- a/drivers/xen/blktap2/device.c +++ b/drivers/xen/blktap2/device.c @@ -3,6 +3,7 @@ #include <linux/cdrom.h> #include <linux/hdreg.h> #include <linux/module.h> +#include <asm/tlbflush.h> #include <scsi/scsi.h> #include <scsi/scsi_ioctl.h> @@ -163,7 +164,6 @@ blktap_map_uaddr_fn(pte_t *ptep, struct BTDBG("ptep %p -> %012llx\n", ptep, pte_val(*pte)); set_pte(ptep, *pte); - xen_invlpg(addr); return 0; } @@ -182,7 +182,6 @@ blktap_umap_uaddr_fn(pte_t *ptep, struct BTDBG("ptep %p\n", ptep); pte_clear(mm, addr, ptep); - xen_invlpg(addr); return 0; } @@ -322,6 +321,7 @@ blktap_unmap(struct blktap *tap, struct if (request->handles[i].kernel == INVALID_GRANT_HANDLE) { kvaddr = request_to_kaddr(request, i); blktap_umap_uaddr(&init_mm, kvaddr); + flush_tlb_kernel_range(kvaddr, kvaddr + PAGE_SIZE); set_phys_to_machine(__pa(kvaddr) >> PAGE_SHIFT, INVALID_P2M_ENTRY); } @@ -551,7 +551,9 @@ blktap_map(struct blktap *tap, pte = mk_pte(page, ring->vma->vm_page_prot); blktap_map_uaddr(ring->vma->vm_mm, uvaddr, pte_mkwrite(pte)); + flush_tlb_mm(ring->vma->vm_mm); blktap_map_uaddr(&init_mm, kvaddr, mk_pte(page, PAGE_KERNEL)); + flush_tlb_kernel_range(kvaddr, kvaddr + PAGE_SIZE); set_phys_to_machine(__pa(kvaddr) >> PAGE_SHIFT, pte_mfn(pte)); request->handles[seg].kernel = INVALID_GRANT_HANDLE; On Wed, May 27, 2009 at 07:18:44PM +0900, Isaku Yamahata wrote: > On Tue, May 26, 2009 at 11:35:05AM -0700, Xen patchbot-linux-2.6.18-xen wrote: > > diff -r f3a935eb30e0 -r eba6fe6d8d53 drivers/xen/blktap2/device.c > > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > > +++ b/drivers/xen/blktap2/device.c Tue May 26 11:23:16 2009 +0100 > > +static int > > +blktap_map_uaddr_fn(pte_t *ptep, struct page *pmd_page, > > + unsigned long addr, void *data) > > +{ > > + pte_t *pte = (pte_t *)data; > > + > > + BTDBG("ptep %p -> %012llx\n", ptep, pte_val(*pte)); > > + set_pte(ptep, *pte); > > + xen_invlpg(addr); > > + return 0; > > +} > ... > > +static int > > +blktap_umap_uaddr_fn(pte_t *ptep, struct page *pmd_page, > > + unsigned long addr, void *data) > > +{ > > + struct mm_struct *mm = (struct mm_struct *)data; > > + > > + BTDBG("ptep %p\n", ptep); > > + pte_clear(mm, addr, ptep); > > + xen_invlpg(addr); > > + return 0; > > +} > > Hi. Although I looked into this for ia64, I think this is generic. > xen_invlpg() flushes tlb on its cpu and doesn't on other cpus. > But those functions set ptes for all cpus. > So should tlb on all cpus be flushed? Maybe by flush_tlb_page()? > > thanks, -- yamahata _______________________________________________ Xen-ia64-devel mailing list Xen-ia64-devel@lists.xensource.com http://lists.xensource.com/xen-ia64-devel