2011-08-22 12 views
5

Quiero escribir una nueva disciplina de colas tc para el kernel de Linux. El objetivo es hacer cola, por ej. diez paquetes y luego enviarlos a todos (lo sé, eso no es realmente bueno para las redes, pero quiero investigar un poco con eso).Nueva disciplina de colas linux tc para crear ráfagas ... se ha quedado sin conocimiento

Entonces, lo que ya está hecho: tengo un esqueleto de un nuevo módulo (enqueue, dequeue functions, etc.) que también está compilando correctamente y funcionando correctamente (un paquete en cola, un paquete enviado, nada especial)) Lo estoy compilando en ubuntu maverick con las mismas fuentes que el núcleo en ejecución y coloque mi módulo en Makefile y Kconfig.

Me di cuenta de que cada vez que se llama a la función en cola, la función dequeue es llamada por qdisc_restart (en sch_generic.c) y solo se envía un paquete.

Mi problema es: ¿cómo puedo enviar más de un paquete de mi módulo a la interfaz de red, como he recogido para, por ejemplo. 10 paquetes y ahora quiero enviarlos a todos?

Intenté llamar a la función sch_direct_xmit (desde sch_generic.c) con los mismos parámetros que en qdisc_restart (y mecanismos de bloqueo) - pero luego, la compilación de mi módulo falla: el símbolo desconocido sch_direct_xmit (pero greping/proc/kallsyms porque eso me da un resultado). Alguna idea, ¿qué pasa con eso? Si se requiere un cierto código, házmelo saber (Incluí el mismo .h como en sched_generic.c)

BR Christoph

Respuesta

0

creo que la solución más fácil sería utilizar un kthread que despertarías cuando ha puesto en cola 10 paquetes. El kthread sería responsable de consumir los paquetes que hubiera puesto en cola previamente.

Sin algunas muestras de su código que es difícil saber cuáles son la secuencia de eventos que hace que su función de quitar de la cola que se llama, pero es probable que pueda hacer algo así:

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; 
} 

Algo como esto lo haría Sospecho. Código no compilado pero te da una idea de cómo hacer esto.

Cuestiones relacionadas