]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From: http://xenbits.xensource.com/linux-2.6.18-xen.hg?rev/618fc299e2f1 |
2 | # HG changeset 764 patch | |
3 | # User Keir Fraser <keir.fraser@citrix.com> | |
4 | # Date 1229601096 0 | |
5 | # Node ID 618fc299e2f1e222686bc234c48ac70e1104e18d | |
6 | # Parent ff9683032b76f533509191bb9532df10cbb9830b | |
7 | Subject: netback: handle non-netback foreign pages | |
8 | Patch-mainline: obsolete | |
9 | ||
10 | An SKB can contain pages which are foreign but not tracked by netback, | |
11 | such as those created by gnttab_copy_grant_page when in | |
12 | NETBK_DELAYED_COPY_SKB mode. These pages do not have a mapping field | |
13 | which points to a valid offset in the pending_tx_info array. | |
14 | ||
15 | Signed-off-by: Ian Campbell <ian.campbell@citrix.com> | |
16 | Acked-by: jbeulich@novell.com | |
17 | ||
18 | --- head-2008-12-23.orig/drivers/xen/netback/netback.c 2008-12-01 11:25:57.000000000 +0100 | |
19 | +++ head-2008-12-23/drivers/xen/netback/netback.c 2008-12-23 09:31:07.000000000 +0100 | |
20 | @@ -40,9 +40,6 @@ | |
21 | ||
22 | /*define NETBE_DEBUG_INTERRUPT*/ | |
23 | ||
24 | -/* extra field used in struct page */ | |
25 | -#define netif_page_index(pg) (*(long *)&(pg)->mapping) | |
26 | - | |
27 | struct netbk_rx_meta { | |
28 | skb_frag_t frag; | |
29 | int id; | |
30 | @@ -89,6 +86,25 @@ static inline unsigned long idx_to_kaddr | |
31 | return (unsigned long)pfn_to_kaddr(idx_to_pfn(idx)); | |
32 | } | |
33 | ||
34 | +/* extra field used in struct page */ | |
35 | +static inline void netif_set_page_index(struct page *pg, unsigned int index) | |
36 | +{ | |
37 | + *(unsigned long *)&pg->mapping = index; | |
38 | +} | |
39 | + | |
40 | +static inline int netif_page_index(struct page *pg) | |
41 | +{ | |
42 | + unsigned long idx = (unsigned long)pg->mapping; | |
43 | + | |
44 | + if (!PageForeign(pg)) | |
45 | + return -1; | |
46 | + | |
47 | + if ((idx >= MAX_PENDING_REQS) || (mmap_pages[idx] != pg)) | |
48 | + return -1; | |
49 | + | |
50 | + return idx; | |
51 | +} | |
52 | + | |
53 | #define PKT_PROT_LEN 64 | |
54 | ||
55 | static struct pending_tx_info { | |
56 | @@ -370,6 +386,7 @@ static u16 netbk_gop_frag(netif_t *netif | |
57 | multicall_entry_t *mcl; | |
58 | netif_rx_request_t *req; | |
59 | unsigned long old_mfn, new_mfn; | |
60 | + int idx = netif_page_index(page); | |
61 | ||
62 | old_mfn = virt_to_mfn(page_address(page)); | |
63 | ||
64 | @@ -380,9 +397,8 @@ static u16 netbk_gop_frag(netif_t *netif | |
65 | meta->copy = 1; | |
66 | copy_gop = npo->copy + npo->copy_prod++; | |
67 | copy_gop->flags = GNTCOPY_dest_gref; | |
68 | - if (PageForeign(page)) { | |
69 | - struct pending_tx_info *src_pend = | |
70 | - &pending_tx_info[netif_page_index(page)]; | |
71 | + if (idx > -1) { | |
72 | + struct pending_tx_info *src_pend = &pending_tx_info[idx]; | |
73 | copy_gop->source.domid = src_pend->netif->domid; | |
74 | copy_gop->source.u.ref = src_pend->req.gref; | |
75 | copy_gop->flags |= GNTCOPY_source_gref; | |
76 | @@ -1437,8 +1453,10 @@ static void netif_idx_release(u16 pendin | |
77 | ||
78 | static void netif_page_release(struct page *page, unsigned int order) | |
79 | { | |
80 | + int idx = netif_page_index(page); | |
81 | BUG_ON(order); | |
82 | - netif_idx_release(netif_page_index(page)); | |
83 | + BUG_ON(idx < 0); | |
84 | + netif_idx_release(idx); | |
85 | } | |
86 | ||
87 | irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs) | |
88 | @@ -1572,7 +1590,7 @@ static int __init netback_init(void) | |
89 | for (i = 0; i < MAX_PENDING_REQS; i++) { | |
90 | page = mmap_pages[i]; | |
91 | SetPageForeign(page, netif_page_release); | |
92 | - netif_page_index(page) = i; | |
93 | + netif_set_page_index(page, i); | |
94 | INIT_LIST_HEAD(&pending_inuse[i].list); | |
95 | } | |
96 |