在内核中使用线程与skb队列发送数据

在内核中我们发送数据一般使用dev_queue_xmit. 但是每次都需要通读等待返回, 通过线程的方式, 可以实现异步模式, 无需等待发送完成.可以大大加快发送速度.以下是示例代码:

static int xmit_thread_worker(void *arg); /////////////////////////////////////////////////////////////////////////////// static struct task_struct *xmit_thread = NULL; // 等待线程启动与完成 static struct completion start_done; static struct completion end_done; // 线程状态 static u32 thread_state = 0x0; // 终止线程标记 static volatile u32 xmit_stop = 0x0; // skb发送队列 struct sk_buff_head pkt_xmit; /////////////////////////////////////////////////////////////////////////////// int xmit_thread_init(void) { int rc = 0x0; // 初始化队列与completion skb_queue_head_init( &pkt_xmit ); init_completion( &start_done ); init_completion( &end_done ); // 创建线程 xmit_thread = kthread_create( xmit_thread_worker, NULL, " "); if ( IS_ERR( xmit_thread ) ) { xmit_thread = NULL; pr_err( "kthread_create occur error./n" ); rc = -1; } else { pr_emerg( "kthread_create success./n" ); // 唤醒线程 wake_up_process( xmit_thread ); // 等待线程启动完成 wait_for_completion( &start_done ); pr_emerg( "xmit thread worker run success./n" ); } return rc; } // skb入队列发送 void xmit_enqueue( struct sk_buff *skb ) { // skb 入队列 skb_queue_tail( &pkt_xmit, skb ); if ( NULL != xmit_thread ){ // 唤醒线程 wake_up_process( xmit_thread ); } } // 销毁线程 void xmit_thread_fini(void) { struct sk_buff *skb = NULL; pr_emerg( "wait for xmit thread done/n" ); if ( NULL == xmit_thread ){ return ; } // 设置线程终止标记 xmit_stop = 0x1; // 等待完成 wait_for_completion( &end_done ); // 释放队列中未发送skb do { skb = __skb_dequeue( &pkt_xmit ); if ( NULL != skb ) { kfree_skb( skb ); } }while( NULL != skb ); } static int xmit_thread_worker(void *arg) { struct sk_buff *skb = NULL; // 通知启动完成 complete( &start_done ); while( 1 ) { thread_state = 0x0; // 调度 schedule_timeout_interruptible(2); //__set_current_state(TASK_RUNNING); thread_state = 0x1; // 是否终止? if ( xmit_stop ) { pr_emerg( "%s end./n", __func__ ); break; } do { // 取skb发送队列并发送 skb = skb_dequeue( &pkt_xmit ); if ( NULL != skb ) { dev_queue_xmit( skb ); } // 是否终止? if ( xmit_stop ) { pr_emerg( "%s end./n", __func__ ); goto _out; } }while( NULL != skb ); }; _out: // 通知线程终止 complete( &end_done ); return 0; }

你可能感兴趣的:(thread,struct,null,UP)