# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1229601096 0
# Node ID 618fc299e2f1e222686bc234c48ac70e1104e18d
# Parent ff9683032b76f533509191bb9532df10cbb9830b
netback: handle non-netback foreign pages
An SKB can contain pages which are foreign but not tracked by netback,
such as those created by gnttab_copy_grant_page when in
NETBK_DELAYED_COPY_SKB mode. These pages do not have a mapping field
which points to a valid offset in the pending_tx_info array.
Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
---
drivers/xen/netback/netback.c | 34 ++++++++++++++++++++++++++--------
1 files changed, 26 insertions(+), 8 deletions(-)
diff -r ff9683032b76 -r 618fc299e2f1 drivers/xen/netback/netback.c
--- a/drivers/xen/netback/netback.c Sat Dec 13 16:00:43 2008 +0000
+++ b/drivers/xen/netback/netback.c Thu Dec 18 11:51:36 2008 +0000
@@ -40,9 +40,6 @@
/*define NETBE_DEBUG_INTERRUPT*/
-/* extra field used in struct page */
-#define netif_page_index(pg) (*(long *)&(pg)->mapping)
-
struct netbk_rx_meta {
skb_frag_t frag;
int id;
@@ -87,6 +84,25 @@ static inline unsigned long idx_to_kaddr
static inline unsigned long idx_to_kaddr(unsigned int idx)
{
return (unsigned long)pfn_to_kaddr(idx_to_pfn(idx));
+}
+
+/* extra field used in struct page */
+static inline void netif_set_page_index(struct page *pg, unsigned int index)
+{
+ *(unsigned long *)&pg->mapping = index;
+}
+
+static inline int netif_page_index(struct page *pg)
+{
+ unsigned long idx = (unsigned long)pg->mapping;
+
+ if (!PageForeign(pg))
+ return -1;
+
+ if ((idx >= MAX_PENDING_REQS) || (mmap_pages[idx] != pg))
+ return -1;
+
+ return idx;
}
#define PKT_PROT_LEN 64
@@ -370,6 +386,7 @@ static u16 netbk_gop_frag(netif_t *netif
multicall_entry_t *mcl;
netif_rx_request_t *req;
unsigned long old_mfn, new_mfn;
+ int idx = netif_page_index(page);
old_mfn = virt_to_mfn(page_address(page));
@@ -380,9 +397,8 @@ static u16 netbk_gop_frag(netif_t *netif
meta->copy = 1;
copy_gop = npo->copy + npo->copy_prod++;
copy_gop->flags = GNTCOPY_dest_gref;
- if (PageForeign(page)) {
- struct pending_tx_info *src_pend =
- &pending_tx_info[netif_page_index(page)];
+ if (idx > -1) {
+ struct pending_tx_info *src_pend =
&pending_tx_info[idx];
copy_gop->source.domid = src_pend->netif->domid;
copy_gop->source.u.ref = src_pend->req.gref;
copy_gop->flags |= GNTCOPY_source_gref;
@@ -1437,8 +1453,10 @@ static void netif_idx_release(u16 pendin
static void netif_page_release(struct page *page, unsigned int order)
{
+ int idx = netif_page_index(page);
BUG_ON(order);
- netif_idx_release(netif_page_index(page));
+ BUG_ON(idx < 0);
+ netif_idx_release(idx);
}
irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs)
@@ -1572,7 +1590,7 @@ static int __init netback_init(void)
for (i = 0; i < MAX_PENDING_REQS; i++) {
page = mmap_pages[i];
SetPageForeign(page, netif_page_release);
- netif_page_index(page) = i;
+ netif_set_page_index(page, i);
INIT_LIST_HEAD(&pending_inuse[i].list);
}
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|