开发者

New linux tc queuing discipline to create bursts...ran out of knowledge

I want to write a new tc queuing discipline for the linux kernel. The goal is to queue up eg. ten packets and then send them all out (I know, that's not really a good thing for networking, but I want to do some research with that).

So, what's already done: I have a skeleton of a new sched-module (enqueue, dequeue functions and so on), which is a开发者_StackOverflow社区lso correctly compiling and correctly working (one packet queued, one packet send out- nothing special). I'm compiling it on ubuntu maverick with the same sources as the running kernel and put my module in the Makefile and Kconfig.

I figured out, that every time the enqueue function is called, thereafter the dequeue function is called by qdisc_restart (in sch_generic.c)- and only one packet is sent out.

My problem is: how can I send more than one packet from my module to the network interface, like I collected for eg. 10 packets and now I want to send them all out?

I tried to call the sch_direct_xmit function (from sch_generic.c) with the same parameters as in qdisc_restart (and locking mechanisms)- but then, the compilation of my module fails: unknown symbol sch_direct_xmit (but greping /proc/kallsyms for that gives me a result). Any idea, what's wrong with that? If some code is required, just let me know (I included the same .h as in sched_generic.c)

BR Christoph


I think the easiest solution would be to use a kthread that you would wake up when you have queued 10 packets. The kthread would be responsible for consuming the packets you'd have previously queued.

Without some samples of your code it is hard to know what are the sequence of events that makes your dequeue function being called but you can probably do something like that:

static struct sk_buff_head foo_skb_queue;
static DECLARE_WAIT_QUEUE_HEAD(food_wqh);

int food_sender(void* unused)
{
        struct sk_buff* skb = NULL;
        unsigned int i = 0;

        while (!kthread_should_stop()) {

                while (skb = skb_dequeue(&foo_skb_queue) && i < NUMBER_TO_SEND) {
                         send_packet(skb);
                         ++i;
                }

                DECLARE_WAITQUEUE(wq, current);
                set_current_state(TASK_INTERRUPTIBLE);
                add_wait_queue(&food_wqh, &wq);

                /* Avoid wake-up lost race */
                if (skb_queue_len(&foo_skb_queue) < NUMBER_TO_SEND)
                        schedule();

                remove_wait_queue(&food_wqh, &wq);
        }
        return 0;
}

int foo_enqueue(struct sk_buff* skb)
{
        skb_queue_tail(&foo_skb, skb);       
        if (skb_queue_len(&foo_skb) >= NUMBER_TO_SEND)
                wake_up(&food_wqh);

        return 0;
}

Something like this would do it I suspect. Code not compiled but it gives you an idea on how to do this.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜