[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Change semantics of gnttab_transfer to take the page away
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 52020caa244f9c86c434b8332783c1edc658d852 # Parent e336e186e5f96a0e93f842ca3a2e39601c2a0193 Change semantics of gnttab_transfer to take the page away from the calling domain, even on error (except for special error GNTST_bad_page). This has a knock-on advantage of simplifying Linux's netback driver. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> diff -r e336e186e5f9 -r 52020caa244f linux-2.6-xen-sparse/drivers/xen/netback/netback.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Mon Nov 21 16:30:43 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Mon Nov 21 17:10:35 2005 @@ -97,27 +97,6 @@ mfn = mfn_list[--alloc_index]; spin_unlock_irqrestore(&mfn_lock, flags); return mfn; -} - -static void free_mfn(unsigned long mfn) -{ - unsigned long flags; - struct xen_memory_reservation reservation = { - .extent_start = &mfn, - .nr_extents = 1, - .extent_order = 0, - .domid = DOMID_SELF - }; - spin_lock_irqsave(&mfn_lock, flags); - if ( alloc_index != MAX_MFN_ALLOC ) - mfn_list[alloc_index++] = mfn; - else { - int ret; - ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, - &reservation); - BUG_ON(ret != 1); - } - spin_unlock_irqrestore(&mfn_lock, flags); } static inline void maybe_schedule_tx_action(void) @@ -306,14 +285,18 @@ netif->stats.tx_packets++; /* The update_va_mapping() must not fail. */ - BUG_ON(mcl[0].result != 0); + BUG_ON(mcl->result != 0); /* Check the reassignment error code. */ status = NETIF_RSP_OKAY; if (gop->status != 0) { DPRINTK("Bad status %d from grant transfer to DOM%u\n", gop->status, netif->domid); - free_mfn(old_mfn); + /* + * Page no longer belongs to us unless GNTST_bad_page, + * but that should be a fatal error anyway. + */ + BUG_ON(gop->status == GNTST_bad_page); status = NETIF_RSP_ERROR; } irq = netif->irq; diff -r e336e186e5f9 -r 52020caa244f xen/common/grant_table.c --- a/xen/common/grant_table.c Mon Nov 21 16:30:43 2005 +++ b/xen/common/grant_table.c Mon Nov 21 17:10:35 2005 @@ -714,26 +714,18 @@ /* Read from caller address space. */ if ( unlikely(__copy_from_user(&gop, &uop[i], sizeof(gop))) ) { - /* Caller error: bail immediately. */ DPRINTK("gnttab_transfer: error reading req %d/%d\n", i, count); - return -EFAULT; + (void)__put_user(GNTST_bad_page, &uop[i].status); + return -EFAULT; /* This is *very* fatal. */ } /* Check the passed page frame for basic validity. */ page = &frame_table[gop.mfn]; if ( unlikely(!pfn_valid(gop.mfn) || IS_XEN_HEAP_FRAME(page)) ) { - /* Caller error: bail immediately. */ DPRINTK("gnttab_transfer: out-of-range or xen frame %lx\n", (unsigned long)gop.mfn); - return -EINVAL; - } - - /* Find the target domain. */ - if ( unlikely((e = find_domain_by_id(gop.domid)) == NULL) ) - { - DPRINTK("gnttab_transfer: can't find domain %d\n", gop.domid); - (void)__put_user(GNTST_bad_domain, &uop[i].status); + (void)__put_user(GNTST_bad_page, &uop[i].status); continue; } @@ -752,15 +744,14 @@ x = y; if (unlikely((x & (PGC_count_mask|PGC_allocated)) != (1 | PGC_allocated)) || unlikely(_nd != _d)) { - /* Caller error: bail immediately. */ DPRINTK("gnttab_transfer: Bad page %p: ed=%p(%u), sd=%p," " caf=%08x, taf=%" PRtype_info "\n", (void *) page_to_pfn(page), d, d->domain_id, unpickle_domptr(_nd), x, page->u.inuse.type_info); spin_unlock(&d->page_alloc_lock); - put_domain(e); - return -EINVAL; + (void)__put_user(GNTST_bad_page, &uop[i].status); + continue; } __asm__ __volatile__( LOCK_PREFIX "cmpxchg8b %2" @@ -778,6 +769,16 @@ list_del(&page->list); spin_unlock(&d->page_alloc_lock); + + /* Find the target domain. */ + if ( unlikely((e = find_domain_by_id(gop.domid)) == NULL) ) + { + DPRINTK("gnttab_transfer: can't find domain %d\n", gop.domid); + (void)__put_user(GNTST_bad_domain, &uop[i].status); + page->count_info &= ~(PGC_count_mask|PGC_allocated); + free_domheap_page(page); + continue; + } spin_lock(&e->page_alloc_lock); @@ -797,6 +798,8 @@ spin_unlock(&e->page_alloc_lock); put_domain(e); (void)__put_user(GNTST_general_error, &uop[i].status); + page->count_info &= ~(PGC_count_mask|PGC_allocated); + free_domheap_page(page); continue; } diff -r e336e186e5f9 -r 52020caa244f xen/common/page_alloc.c --- a/xen/common/page_alloc.c Mon Nov 21 16:30:43 2005 +++ b/xen/common/page_alloc.c Mon Nov 21 17:10:35 2005 @@ -645,7 +645,9 @@ } else { - /* Freeing an anonymous domain-heap page. */ + /* Freeing anonymous domain-heap pages. */ + for ( i = 0; i < (1 << order); i++ ) + pg[i].u.free.cpumask = CPU_MASK_NONE; free_heap_pages(pfn_dom_zone_type(page_to_pfn(pg)), pg, order); drop_dom_ref = 0; } diff -r e336e186e5f9 -r 52020caa244f xen/include/public/grant_table.h --- a/xen/include/public/grant_table.h Mon Nov 21 16:30:43 2005 +++ b/xen/include/public/grant_table.h Mon Nov 21 17:10:35 2005 @@ -215,9 +215,12 @@ } gnttab_dump_table_t; /* - * GNTTABOP_transfer_grant_ref: Transfer <frame> to a foreign domain. The - * foreign domain has previously registered the details of the transfer. - * These can be identified from <handle>, a grant reference. + * GNTTABOP_transfer_grant_ref: Transfer <frame> to a foreign domain. The + * foreign domain has previously registered its interest in the transfer via + * <domid, ref>. + * + * Note that, even if the transfer fails, the specified page no longer belongs + * to the calling domain *unless* the error is GNTST_bad_page. */ #define GNTTABOP_transfer 4 typedef struct { @@ -269,6 +272,7 @@ #define GNTST_bad_dev_addr (-6) /* Inappropriate device address to unmap.*/ #define GNTST_no_device_space (-7) /* Out of space in I/O MMU. */ #define GNTST_permission_denied (-8) /* Not enough privilege for operation. */ +#define GNTST_bad_page (-9) /* Specified page was invalid for op. */ #define GNTTABOP_error_msgs { \ "okay", \ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |