This commit is contained in:
emellor@leeni.uk.xensource.com committed 2005-11-21 14:48:31 +01:00
commit ea8c03c331
4 files changed
+80 -88

No files matched your search

+20 -11
View File
@@ -229,20 +229,29 @@ gnttab_grant_foreign_transfer_ref(grant_ref_t ref, domid_t domid)
unsigned long
gnttab_end_foreign_transfer_ref(grant_ref_t ref)
{
unsigned long frame = 0;
unsigned long frame;
u16 flags;
flags = shared[ref].flags;
/*
* If a transfer is committed then wait for the frame address to
* appear. Otherwise invalidate the grant entry against future use.
*/
if (likely(flags != GTF_accept_transfer) ||
(synch_cmpxchg(&shared[ref].flags, flags, 0) !=
GTF_accept_transfer))
while (unlikely((frame = shared[ref].frame) == 0))
cpu_relax();
* If a transfer is not even yet started, try to reclaim the grant
* reference and return failure (== 0).
*/
while (!((flags = shared[ref].flags) & GTF_transfer_committed)) {
if ( synch_cmpxchg(&shared[ref].flags, flags, 0) == flags )
return 0;
cpu_relax();
}
/* If a transfer is in progress then wait until it is completed. */
while (!(flags & GTF_transfer_completed)) {
flags = shared[ref].flags;
cpu_relax();
}
/* Read the frame number /after/ reading completion status. */
rmb();
frame = shared[ref].frame;
BUG_ON(frame == 0);
return frame;
}
@@ -99,7 +99,6 @@ static unsigned long alloc_mfn(void)
return mfn;
}
#if 0
static void free_mfn(unsigned long mfn)
{
unsigned long flags;
@@ -120,7 +119,6 @@ static void free_mfn(unsigned long mfn)
}
spin_unlock_irqrestore(&mfn_lock, flags);
}
#endif
static inline void maybe_schedule_tx_action(void)
{
@@ -287,28 +285,19 @@ static void net_rx_action(unsigned long unused)
ret = HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl);
BUG_ON(ret != 0);
mcl = rx_mcl;
if( HYPERVISOR_grant_table_op(GNTTABOP_transfer, grant_rx_op,
gop - grant_rx_op)) {
/*
* The other side has given us a bad grant ref, or has no
* headroom, or has gone away. Unfortunately the current grant
* table code doesn't inform us which is the case, so not much
* we can do.
*/
DPRINTK("net_rx: transfer to DOM%u failed; dropping (up to) "
"%d packets.\n",
grant_rx_op[0].domid, gop - grant_rx_op);
}
gop = grant_rx_op;
ret = HYPERVISOR_grant_table_op(GNTTABOP_transfer, grant_rx_op,
gop - grant_rx_op);
BUG_ON(ret != 0);
mcl = rx_mcl;
gop = grant_rx_op;
while ((skb = __skb_dequeue(&rxq)) != NULL) {
netif = netdev_priv(skb->dev);
size = skb->tail - skb->data;
/* Rederive the machine addresses. */
new_mfn = mcl[0].args[1] >> PAGE_SHIFT;
old_mfn = 0; /* XXX Fix this so we can free_mfn() on error! */
new_mfn = mcl->args[1] >> PAGE_SHIFT;
old_mfn = gop->mfn;
atomic_set(&(skb_shinfo(skb)->dataref), 1);
skb_shinfo(skb)->nr_frags = 0;
skb_shinfo(skb)->frag_list = NULL;
@@ -321,10 +310,10 @@ static void net_rx_action(unsigned long unused)
/* Check the reassignment error code. */
status = NETIF_RSP_OKAY;
if(gop->status != 0) {
if (gop->status != 0) {
DPRINTK("Bad status %d from grant transfer to DOM%u\n",
gop->status, netif->domid);
/* XXX SMH: should free 'old_mfn' here */
free_mfn(old_mfn);
status = NETIF_RSP_ERROR;
}
irq = netif->irq;
@@ -739,14 +739,23 @@ static int netif_poll(struct net_device *dev, int *pbudget)
(i != rp) && (work_done < budget);
i++, work_done++) {
rx = &np->rx->ring[MASK_NETIF_RX_IDX(i)].resp;
/*
* An error here is very odd. Usually indicates a backend bug,
* low-mem condition, or we didn't have reservation headroom.
*/
if (unlikely(rx->status <= 0)) {
* This definitely indicates a bug, either in this driver or
* in the backend driver. In future this should flag the bad
* situation to the system controller to reboot the backed.
*/
if ((ref = np->grant_rx_ref[rx->id]) == GRANT_INVALID_REF) {
WPRINTK("Bad rx response id %d.\n", rx->id);
work_done--;
continue;
}
/* Memory pressure, insufficient buffer headroom, ... */
if ((mfn = gnttab_end_foreign_transfer_ref(ref)) == 0) {
if (net_ratelimit())
printk(KERN_WARNING "Bad rx buffer "
"(memory squeeze?).\n");
WPRINTK("Unfulfilled rx req (id=%d, st=%d).\n",
rx->id, rx->status);
np->rx->ring[MASK_NETIF_RX_IDX(np->rx->req_prod)].
req.id = rx->id;
wmb();
@@ -755,23 +764,8 @@ static int netif_poll(struct net_device *dev, int *pbudget)
continue;
}
ref = np->grant_rx_ref[rx->id];
if(ref == GRANT_INVALID_REF) {
printk(KERN_WARNING "Bad rx grant reference %d "
"from dom %d.\n",
ref, np->xbdev->otherend_id);
np->rx->ring[MASK_NETIF_RX_IDX(np->rx->req_prod)].
req.id = rx->id;
wmb();
np->rx->req_prod++;
work_done--;
continue;
}
np->grant_rx_ref[rx->id] = GRANT_INVALID_REF;
mfn = gnttab_end_foreign_transfer_ref(ref);
gnttab_release_grant_reference(&np->gref_rx_head, ref);
np->grant_rx_ref[rx->id] = GRANT_INVALID_REF;
skb = np->rx_skbs[rx->id];
ADD_ID_TO_FREELIST(np->rx_skbs, rx->id);
+35 -35
View File
@@ -706,35 +706,34 @@ gnttab_transfer(
struct pfn_info *page;
u32 _d, _nd, x, y;
int i;
int result = GNTST_okay;
grant_entry_t *sha;
gnttab_transfer_t gop;
for ( i = 0; i < count; i++ )
{
gnttab_transfer_t *gop = &uop[i];
/* 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;
}
page = &frame_table[gop->mfn];
if ( unlikely(IS_XEN_HEAP_FRAME(page)))
/* Check the passed page frame for basic validity. */
page = &frame_table[gop.mfn];
if ( unlikely(!pfn_valid(gop.mfn) || IS_XEN_HEAP_FRAME(page)) )
{
printk("gnttab_transfer: xen heap frame mfn=%lx\n",
(unsigned long) gop->mfn);
gop->status = GNTST_bad_virt_addr;
continue;
}
if ( unlikely(!pfn_valid(page_to_pfn(page))) )
{
printk("gnttab_transfer: invalid pfn for mfn=%lx\n",
(unsigned long) gop->mfn);
gop->status = GNTST_bad_virt_addr;
continue;
/* Caller error: bail immediately. */
DPRINTK("gnttab_transfer: out-of-range or xen frame %lx\n",
(unsigned long)gop.mfn);
return -EINVAL;
}
if ( unlikely((e = find_domain_by_id(gop->domid)) == NULL) )
/* Find the target domain. */
if ( unlikely((e = find_domain_by_id(gop.domid)) == NULL) )
{
printk("gnttab_transfer: can't find domain %d\n", gop->domid);
gop->status = GNTST_bad_domain;
DPRINTK("gnttab_transfer: can't find domain %d\n", gop.domid);
(void)__put_user(GNTST_bad_domain, &uop[i].status);
continue;
}
@@ -752,15 +751,16 @@ gnttab_transfer(
do {
x = y;
if (unlikely((x & (PGC_count_mask|PGC_allocated)) !=
(1 | PGC_allocated)) || unlikely(_nd != _d)) {
printk("gnttab_transfer: Bad page values %p: ed=%p(%u), sd=%p,"
(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 0;
return -EINVAL;
}
__asm__ __volatile__(
LOCK_PREFIX "cmpxchg8b %2"
@@ -788,16 +788,16 @@ gnttab_transfer(
*/
if ( unlikely(test_bit(_DOMF_dying, &e->domain_flags)) ||
unlikely(e->tot_pages >= e->max_pages) ||
unlikely(!gnttab_prepare_for_transfer(e, d, gop->ref)) )
unlikely(!gnttab_prepare_for_transfer(e, d, gop.ref)) )
{
DPRINTK("gnttab_transfer: Transferee has no reservation headroom "
"(%d,%d) or provided a bad grant ref (%08x) or "
"is dying (%lx)\n",
e->tot_pages, e->max_pages, gop->ref, e->domain_flags);
e->tot_pages, e->max_pages, gop.ref, e->domain_flags);
spin_unlock(&e->page_alloc_lock);
put_domain(e);
gop->status = result = GNTST_general_error;
break;
(void)__put_user(GNTST_general_error, &uop[i].status);
continue;
}
/* Okay, add the page to 'e'. */
@@ -805,23 +805,23 @@ gnttab_transfer(
get_knownalive_domain(e);
list_add_tail(&page->list, &e->page_list);
page_set_owner(page, e);
spin_unlock(&e->page_alloc_lock);
TRACE_1D(TRC_MEM_PAGE_GRANT_TRANSFER, e->domain_id);
/* Tell the guest about its new page frame. */
sha = &e->grant_table->shared[gop->ref];
sha->frame = gop->mfn;
sha = &e->grant_table->shared[gop.ref];
sha->frame = gop.mfn;
wmb();
sha->flags |= GTF_transfer_completed;
put_domain(e);
gop->status = GNTST_okay;
(void)__put_user(GNTST_okay, &uop[i].status);
}
return result;
return 0;
}
long
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.