debuggers.hg

view tools/remus/kmod/sch_queue.c @ 20950:989014ce7b4a

Remus: fix ia64 build

This patch fixes the following error:
/xen-unstable.hg/tools/remus/kmod/sch_queue.c: In function
`is_foreign':
/xen-unstable.hg/tools/remus/kmod/sch_queue.c:51: error:
`phys_to_machine_mapping' undeclared (first use in this function)

Signed-off-by: KUWAMURA Shin'ya <kuwa@jp.fujitsu.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Feb 05 10:37:24 2010 +0000 (2010-02-05)
parents 1c8c18ae1d3b
children 373daaeb636e
line source
1 /*
2 * sch_queue.c Queue traffic until an explicit release command
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * The operation of the buffer is as follows:
10 * When a checkpoint begins, a barrier is inserted into the
11 * network queue by a netlink request (it operates by storing
12 * a pointer to the next packet which arrives and blocking dequeue
13 * when that packet is at the head of the queue).
14 * When a checkpoint completes (the backup acknowledges receipt),
15 * currently-queued packets are released.
16 * So it supports two operations, barrier and release.
17 */
19 #include <linux/config.h>
20 #include <linux/module.h>
21 #include <linux/types.h>
22 #include <linux/kernel.h>
23 #include <linux/errno.h>
24 #include <linux/netdevice.h>
25 #include <linux/skbuff.h>
26 #include <net/pkt_sched.h>
28 /* xenbus directory */
29 #define FIFO_BUF (10*1024*1024)
31 #define TCQ_CHECKPOINT 0
32 #define TCQ_DEQUEUE 1
34 struct queue_sched_data {
35 /* this packet is the first packet which should not be delivered.
36 * If it is NULL, queue_enqueue will set it to the next packet it sees. */
37 struct sk_buff *stop;
38 };
40 struct tc_queue_qopt {
41 /* 0: reset stop packet pointer
42 * 1: dequeue to stop pointer */
43 int action;
44 };
46 /* borrowed from drivers/xen/netback/loopback.c */
47 #ifdef CONFIG_X86
48 static int is_foreign(unsigned long pfn)
49 {
50 /* NB. Play it safe for auto-translation mode. */
51 return (xen_feature(XENFEAT_auto_translated_physmap) ||
52 (phys_to_machine_mapping[pfn] & FOREIGN_FRAME_BIT));
53 }
54 #else
55 /* How to detect a foreign mapping? Play it safe. */
56 #define is_foreign(pfn) (1)
57 #endif
59 static int skb_remove_foreign_references(struct sk_buff *skb)
60 {
61 struct page *page;
62 unsigned long pfn;
63 int i, off;
64 char *vaddr;
66 BUG_ON(skb_shinfo(skb)->frag_list);
68 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
69 pfn = page_to_pfn(skb_shinfo(skb)->frags[i].page);
70 if (!is_foreign(pfn))
71 continue;
72 /*
73 printk("foreign ref found\n");
74 */
75 page = alloc_page(GFP_ATOMIC | __GFP_NOWARN);
76 if (unlikely(!page))
77 return 0;
79 vaddr = kmap_skb_frag(&skb_shinfo(skb)->frags[i]);
80 off = skb_shinfo(skb)->frags[i].page_offset;
81 memcpy(page_address(page) + off, vaddr + off,
82 skb_shinfo(skb)->frags[i].size);
83 kunmap_skb_frag(vaddr);
85 put_page(skb_shinfo(skb)->frags[i].page);
86 skb_shinfo(skb)->frags[i].page = page;
87 }
89 return 1;
90 }
92 static int queue_enqueue(struct sk_buff *skb, struct Qdisc* sch)
93 {
94 struct queue_sched_data *q = qdisc_priv(sch);
96 if (likely(sch->qstats.backlog + skb->len <= FIFO_BUF))
97 {
98 if (!q->stop)
99 q->stop = skb;
101 if (!skb_remove_foreign_references(skb)) {
102 printk("error removing foreign ref\n");
103 return qdisc_reshape_fail(skb, sch);
104 }
106 return qdisc_enqueue_tail(skb, sch);
107 }
108 printk("queue reported full: %d,%d\n", sch->qstats.backlog, skb->len);
110 return qdisc_reshape_fail(skb, sch);
111 }
113 /* dequeue doesn't actually dequeue until the release command is
114 * received. */
115 static inline struct sk_buff *queue_dequeue(struct Qdisc* sch)
116 {
117 struct queue_sched_data *q = qdisc_priv(sch);
118 struct sk_buff* peek;
119 /*
120 struct timeval tv;
122 if (!q->stop) {
123 do_gettimeofday(&tv);
124 printk("packet dequeued at %lu.%06lu\n", tv.tv_sec, tv.tv_usec);
125 }
126 */
128 if (sch->flags & TCQ_F_THROTTLED)
129 return NULL;
131 peek = (struct sk_buff *)((sch->q).next);
133 /* this pointer comparison may be shady */
134 if (peek == q->stop) {
135 /*
136 do_gettimeofday(&tv);
137 printk("stop packet at %lu.%06lu\n", tv.tv_sec, tv.tv_usec);
138 */
140 /* this is the tail of the last round. Release it and block the queue */
141 sch->flags |= TCQ_F_THROTTLED;
142 return NULL;
143 }
145 return qdisc_dequeue_head(sch);
146 }
148 static int queue_init(struct Qdisc *sch, struct rtattr *opt)
149 {
150 sch->flags |= TCQ_F_THROTTLED;
152 return 0;
153 }
155 /* receives two messages:
156 * 0: checkpoint queue (set stop to next packet)
157 * 1: dequeue until stop */
158 static int queue_change(struct Qdisc* sch, struct rtattr* opt)
159 {
160 struct queue_sched_data *q = qdisc_priv(sch);
161 struct tc_queue_qopt* msg;
162 /*
163 struct timeval tv;
164 */
166 if (!opt || RTA_PAYLOAD(opt) < sizeof(*msg))
167 return -EINVAL;
169 msg = RTA_DATA(opt);
171 if (msg->action == TCQ_CHECKPOINT) {
172 /* reset stop */
173 q->stop = NULL;
174 } else if (msg->action == TCQ_DEQUEUE) {
175 /* dequeue */
176 sch->flags &= ~TCQ_F_THROTTLED;
177 netif_schedule(sch->dev);
178 /*
179 do_gettimeofday(&tv);
180 printk("queue release at %lu.%06lu (%d bytes)\n", tv.tv_sec, tv.tv_usec,
181 sch->qstats.backlog);
182 */
183 } else {
184 return -EINVAL;
185 }
187 return 0;
188 }
190 struct Qdisc_ops queue_qdisc_ops = {
191 .id = "queue",
192 .priv_size = sizeof(struct queue_sched_data),
193 .enqueue = queue_enqueue,
194 .dequeue = queue_dequeue,
195 .init = queue_init,
196 .change = queue_change,
197 .owner = THIS_MODULE,
198 };
200 static int __init queue_module_init(void)
201 {
202 printk("loading queue\n");
203 return register_qdisc(&queue_qdisc_ops);
204 }
206 static void __exit queue_module_exit(void)
207 {
208 printk("queue unloaded\n");
209 unregister_qdisc(&queue_qdisc_ops);
210 }
211 module_init(queue_module_init)
212 module_exit(queue_module_exit)
213 MODULE_LICENSE("GPL");