Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 329170
b: refs/heads/master
c: c571898
h: refs/heads/master
v: v3
  • Loading branch information
Andres Lagar-Cavilla authored and Konrad Rzeszutek Wilk committed Sep 21, 2012
1 parent 9bb8a27 commit a5bb955
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 13 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c3cb4709809e655a4ba5a716086c8bc5bbbbccdb
refs/heads/master: c571898ffc24a1768e1b2dabeac0fc7dd4c14601
11 changes: 3 additions & 8 deletions trunk/drivers/net/xen-netback/netback.c
Original file line number Diff line number Diff line change
Expand Up @@ -635,9 +635,7 @@ static void xen_netbk_rx_action(struct xen_netbk *netbk)
return;

BUG_ON(npo.copy_prod > ARRAY_SIZE(netbk->grant_copy_op));
ret = HYPERVISOR_grant_table_op(GNTTABOP_copy, &netbk->grant_copy_op,
npo.copy_prod);
BUG_ON(ret != 0);
gnttab_batch_copy(netbk->grant_copy_op, npo.copy_prod);

while ((skb = __skb_dequeue(&rxq)) != NULL) {
sco = (struct skb_cb_overlay *)skb->cb;
Expand Down Expand Up @@ -1460,18 +1458,15 @@ static void xen_netbk_tx_submit(struct xen_netbk *netbk)
static void xen_netbk_tx_action(struct xen_netbk *netbk)
{
unsigned nr_gops;
int ret;

nr_gops = xen_netbk_tx_build_gops(netbk);

if (nr_gops == 0)
return;
ret = HYPERVISOR_grant_table_op(GNTTABOP_copy,
netbk->tx_copy_ops, nr_gops);
BUG_ON(ret);

xen_netbk_tx_submit(netbk);
gnttab_batch_copy(netbk->tx_copy_ops, nr_gops);

xen_netbk_tx_submit(netbk);
}

static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx)
Expand Down
53 changes: 53 additions & 0 deletions trunk/drivers/xen/grant-table.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <linux/vmalloc.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/hardirq.h>

#include <xen/xen.h>
Expand Down Expand Up @@ -823,6 +824,52 @@ unsigned int gnttab_max_grant_frames(void)
}
EXPORT_SYMBOL_GPL(gnttab_max_grant_frames);

/* Handling of paged out grant targets (GNTST_eagain) */
#define MAX_DELAY 256
static inline void
gnttab_retry_eagain_gop(unsigned int cmd, void *gop, int16_t *status,
const char *func)
{
unsigned delay = 1;

do {
BUG_ON(HYPERVISOR_grant_table_op(cmd, gop, 1));
if (*status == GNTST_eagain)
msleep(delay++);
} while ((*status == GNTST_eagain) && (delay < MAX_DELAY));

if (delay >= MAX_DELAY) {
printk(KERN_ERR "%s: %s eagain grant\n", func, current->comm);
*status = GNTST_bad_page;
}
}

void gnttab_batch_map(struct gnttab_map_grant_ref *batch, unsigned count)
{
struct gnttab_map_grant_ref *op;

if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, batch, count))
BUG();
for (op = batch; op < batch + count; op++)
if (op->status == GNTST_eagain)
gnttab_retry_eagain_gop(GNTTABOP_map_grant_ref, op,
&op->status, __func__);
}
EXPORT_SYMBOL_GPL(gnttab_batch_map);

void gnttab_batch_copy(struct gnttab_copy *batch, unsigned count)
{
struct gnttab_copy *op;

if (HYPERVISOR_grant_table_op(GNTTABOP_copy, batch, count))
BUG();
for (op = batch; op < batch + count; op++)
if (op->status == GNTST_eagain)
gnttab_retry_eagain_gop(GNTTABOP_copy, op,
&op->status, __func__);
}
EXPORT_SYMBOL_GPL(gnttab_batch_copy);

int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
struct gnttab_map_grant_ref *kmap_ops,
struct page **pages, unsigned int count)
Expand All @@ -836,6 +883,12 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
if (ret)
return ret;

/* Retry eagain maps */
for (i = 0; i < count; i++)
if (map_ops[i].status == GNTST_eagain)
gnttab_retry_eagain_gop(GNTTABOP_map_grant_ref, map_ops + i,
&map_ops[i].status, __func__);

if (xen_feature(XENFEAT_auto_translated_physmap))
return ret;

Expand Down
6 changes: 2 additions & 4 deletions trunk/drivers/xen/xenbus/xenbus_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -490,8 +490,7 @@ static int xenbus_map_ring_valloc_pv(struct xenbus_device *dev,

op.host_addr = arbitrary_virt_to_machine(pte).maddr;

if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
BUG();
gnttab_batch_map(&op, 1);

if (op.status != GNTST_okay) {
free_vm_area(area);
Expand Down Expand Up @@ -572,8 +571,7 @@ int xenbus_map_ring(struct xenbus_device *dev, int gnt_ref,
gnttab_set_map_op(&op, (unsigned long)vaddr, GNTMAP_host_map, gnt_ref,
dev->otherend_id);

if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
BUG();
gnttab_batch_map(&op, 1);

if (op.status != GNTST_okay) {
xenbus_dev_fatal(dev, op.status,
Expand Down
12 changes: 12 additions & 0 deletions trunk/include/xen/grant_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,4 +189,16 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops,
struct page **pages, unsigned int count, bool clear_pte);

/* Perform a batch of grant map/copy operations. Retry every batch slot
* for which the hypervisor returns GNTST_eagain. This is typically due
* to paged out target frames.
*
* Will retry for 1, 2, ... 255 ms, i.e. 256 times during 32 seconds.
*
* Return value in each iand every status field of the batch guaranteed
* to not be GNTST_eagain.
*/
void gnttab_batch_map(struct gnttab_map_grant_ref *batch, unsigned count);
void gnttab_batch_copy(struct gnttab_copy *batch, unsigned count);

#endif /* __ASM_GNTTAB_H__ */

0 comments on commit a5bb955

Please sign in to comment.