2011-08-22 15 views
5

Tôi muốn viết một kỷ luật xếp hàng tc mới cho hạt nhân Linux. Mục tiêu là xếp hàng ví dụ. mười gói và sau đó gửi tất cả chúng ra (tôi biết, đó không thực sự là một điều tốt cho mạng, nhưng tôi muốn làm một số nghiên cứu với điều đó). Vì vậy, những gì đã làm: Tôi có một bộ xương của một mô-đun lịch mới (enqueue, dequeue chức năng và vv), mà cũng là một cách chính xác biên dịch và làm việc chính xác (một gói xếp hàng, một gói gửi ra- không có gì đặc biệt). Tôi đang biên dịch nó trên ubuntu maverick với các nguồn giống như hạt nhân đang chạy và đặt mô-đun của tôi trong Makefile và Kconfig.New linux tc xếp hàng kỷ luật để tạo ra các vụ nổ ... hết kiến ​​thức

Tôi đã tìm ra, rằng mỗi khi hàm enqueue được gọi, sau đó hàm dequeue được gọi bởi qdisc_restart (trong sch_generic.c) - và chỉ một gói được gửi đi.

Vấn đề của tôi là: làm cách nào tôi có thể gửi nhiều hơn một gói từ mô-đun của mình đến giao diện mạng, như tôi đã thu thập ví dụ. 10 gói và bây giờ tôi muốn gửi tất cả chúng ra?

Tôi đã thử gọi hàm sch_direct_xmit (từ sch_generic.c) với các tham số giống như trong qdisc_restart (và cơ chế khóa) - nhưng sau đó, việc biên dịch mô-đun của tôi không thành công: biểu tượng không rõ sch_direct_xmit (nhưng greping/proc/kallsyms cho điều đó mang lại cho tôi một kết quả). Bất kỳ ý tưởng, có gì sai với điều đó? Nếu một số mã được yêu cầu, chỉ cho tôi biết (tôi bao gồm các .h giống như trong sched_generic.c)

BR Christoph

Trả lời

0

Tôi nghĩ rằng giải pháp đơn giản nhất là nên sử dụng một kthread mà bạn sẽ thức dậy khi bạn đã xếp hàng 10 gói. Kthread sẽ chịu trách nhiệm cho việc tiêu thụ các gói mà bạn đã xếp hàng trước đó.

Nếu không có một số mẫu mã của bạn rất khó để biết chuỗi các sự kiện mà làm cho chức năng dequeue của bạn được gọi là gì nhưng có lẽ bạn có thể làm một cái gì đó như thế:

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 như thế này sẽ làm điều đó Tôi nghi ngờ. Mã không được biên dịch nhưng nó cung cấp cho bạn một ý tưởng về cách thực hiện điều này.

Các vấn đề liên quan