From mboxrd@z Thu Jan 1 00:00:00 1970 From: Brendan Cully Subject: Re: Re: [PATCH] Remus breaks the build Date: Wed, 18 Aug 2010 13:26:50 -0700 Message-ID: <20100818202650.GD2411@kremvax.cs.ubc.ca> References: <4C6493ED.3040605@goop.org> <20100813194217.GA6981@kremvax.cs.ubc.ca> <4C65B5A5.8020202@goop.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="dDRMvlgZJXvWKvBx" Return-path: Content-Disposition: inline In-Reply-To: <4C65B5A5.8020202@goop.org> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: Jeremy Fitzhardinge Cc: "Xen-devel@lists.xensource.com" , Ian Jackson , Ian Campbell , Stefano Stabellini List-Id: xen-devel@lists.xenproject.org --dDRMvlgZJXvWKvBx Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Friday, 13 August 2010 at 14:14, Jeremy Fitzhardinge wrote: > On 08/13/2010 12:42 PM, Brendan Cully wrote: > > I assume you're talking about this snippet of tools/remus/kmod/Makefile: > > > > $(MAKE) -C $(KERNELDIR) SUBDIRS=`pwd` modules > > > > which expects to find a Makefile in $KERNELDIR but does the actual > > building in place, in the tools/remus/kmod directory (unless the > > kernel build system has changed recently?). I thought this was a > > pretty standard way to build out-of-tree kernel modules. > > I don't ever build the kernel out of the Xen tree. In general, it > assumes the kernel tree has already been configured and built, which may > not be true if you're doing a parallel build, or if you're building the > Xen tree piecewise. > > > I'm not sure why this is causing you problems (is it?), but if you're > > willing to carry sch_queue in the pvops tree, I'd be happy to drop > > tools/remus/kmod in the unstable tree. > > Yes, I'm happy to include it. Do you have a git reference I can merge from? That's more git than I've learned. Would a patch suffice? (even producing the diff was non-obvious. It turns out that git add foo; git diff doesn't include the diff for foo!) --dDRMvlgZJXvWKvBx Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="pvops-sch-queue.diff" diff --git a/net/sched/Kconfig b/net/sched/Kconfig index 929218a..2b945b2 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig @@ -215,6 +215,16 @@ config NET_SCH_INGRESS To compile this code as a module, choose M here: the module will be called sch_ingress. +config NET_SCH_QUEUE + tristate "Remus network buffer" + ---help--- + Say Y here if you are using this kernel for Xen dom0 and + want to protect Xen guests with Remus. + If unsure, say N. + + To compile this code as a module, choose M here: the + module will be called sch_queue. + comment "Classification" config NET_CLS diff --git a/net/sched/Makefile b/net/sched/Makefile index 54d950c..1a17127 100644 --- a/net/sched/Makefile +++ b/net/sched/Makefile @@ -31,6 +31,7 @@ obj-$(CONFIG_NET_SCH_MULTIQ) += sch_multiq.o obj-$(CONFIG_NET_SCH_ATM) += sch_atm.o obj-$(CONFIG_NET_SCH_NETEM) += sch_netem.o obj-$(CONFIG_NET_SCH_DRR) += sch_drr.o +obj-$(CONFIG_NET_SCH_QUEUE) += sch_queue.o obj-$(CONFIG_NET_CLS_U32) += cls_u32.o obj-$(CONFIG_NET_CLS_ROUTE4) += cls_route.o obj-$(CONFIG_NET_CLS_FW) += cls_fw.o diff --git a/net/sched/sch_queue.c b/net/sched/sch_queue.c new file mode 100644 index 0000000..fe11e41 --- /dev/null +++ b/net/sched/sch_queue.c @@ -0,0 +1,172 @@ +/* + * sch_queue.c Queue traffic until an explicit release command + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * The operation of the buffer is as follows: + * When a checkpoint begins, a barrier is inserted into the + * network queue by a netlink request (it operates by storing + * a pointer to the next packet which arrives and blocking dequeue + * when that packet is at the head of the queue). + * When a checkpoint completes (the backup acknowledges receipt), + * currently-queued packets are released. + * So it supports two operations, barrier and release. + */ + +#include +#include +#include +#include +#include +#include +#include + +/* xenbus directory */ +#define FIFO_BUF (10*1024*1024) + +#define TCQ_CHECKPOINT 0 +#define TCQ_DEQUEUE 1 + +struct queue_sched_data { + /* this packet is the first packet which should not be delivered. + * If it is NULL, queue_enqueue will set it to the next packet it sees. */ + struct sk_buff *stop; +}; + +struct tc_queue_qopt { + /* 0: reset stop packet pointer + * 1: dequeue to stop pointer */ + int action; +}; + +static int skb_remove_foreign_references(struct sk_buff *skb) +{ + return !skb_linearize(skb); +} + +static int queue_enqueue(struct sk_buff *skb, struct Qdisc* sch) +{ + struct queue_sched_data *q = qdisc_priv(sch); + + if (likely(sch->qstats.backlog + skb->len <= FIFO_BUF)) + { + if (!q->stop) + q->stop = skb; + + if (!skb_remove_foreign_references(skb)) { + printk("error removing foreign ref\n"); + return qdisc_reshape_fail(skb, sch); + } + + return qdisc_enqueue_tail(skb, sch); + } + printk("queue reported full: %d,%d\n", sch->qstats.backlog, skb->len); + + return qdisc_reshape_fail(skb, sch); +} + +/* dequeue doesn't actually dequeue until the release command is + * received. */ +static struct sk_buff *queue_dequeue(struct Qdisc* sch) +{ + struct queue_sched_data *q = qdisc_priv(sch); + struct sk_buff* peek; + /* + struct timeval tv; + + if (!q->stop) { + do_gettimeofday(&tv); + printk("packet dequeued at %lu.%06lu\n", tv.tv_sec, tv.tv_usec); + } + */ + + if (sch->flags & TCQ_F_THROTTLED) + return NULL; + + peek = (struct sk_buff *)((sch->q).next); + + /* this pointer comparison may be shady */ + if (peek == q->stop) { + /* + do_gettimeofday(&tv); + printk("stop packet at %lu.%06lu\n", tv.tv_sec, tv.tv_usec); + */ + + /* this is the tail of the last round. Release it and block the queue */ + sch->flags |= TCQ_F_THROTTLED; + return NULL; + } + + return qdisc_dequeue_head(sch); +} + +static int queue_init(struct Qdisc *sch, struct nlattr *opt) +{ + sch->flags |= TCQ_F_THROTTLED; + + return 0; +} + +/* receives two messages: + * 0: checkpoint queue (set stop to next packet) + * 1: dequeue until stop */ +static int queue_change(struct Qdisc* sch, struct nlattr* opt) +{ + struct queue_sched_data *q = qdisc_priv(sch); + struct tc_queue_qopt* msg; + /* + struct timeval tv; + */ + + if (!opt || nla_len(opt) < sizeof(*msg)) + return -EINVAL; + + msg = nla_data(opt); + + if (msg->action == TCQ_CHECKPOINT) { + /* reset stop */ + q->stop = NULL; + } else if (msg->action == TCQ_DEQUEUE) { + /* dequeue */ + sch->flags &= ~TCQ_F_THROTTLED; + netif_schedule_queue(sch->dev_queue); + /* + do_gettimeofday(&tv); + printk("queue release at %lu.%06lu (%d bytes)\n", tv.tv_sec, tv.tv_usec, + sch->qstats.backlog); + */ + } else { + return -EINVAL; + } + + return 0; +} + +struct Qdisc_ops queue_qdisc_ops = { + .id = "queue", + .priv_size = sizeof(struct queue_sched_data), + .enqueue = queue_enqueue, + .dequeue = queue_dequeue, + .peek = qdisc_peek_head, + .init = queue_init, + .change = queue_change, + .owner = THIS_MODULE, +}; + +static int __init queue_module_init(void) +{ + printk("loading queue\n"); + return register_qdisc(&queue_qdisc_ops); +} + +static void __exit queue_module_exit(void) +{ + printk("queue unloaded\n"); + unregister_qdisc(&queue_qdisc_ops); +} +module_init(queue_module_init) +module_exit(queue_module_exit) +MODULE_LICENSE("GPL"); --dDRMvlgZJXvWKvBx Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel --dDRMvlgZJXvWKvBx--