久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Android socket創(chuàng)建,、綁定流程分析(三)

 techres 2011-12-31
Android socket創(chuàng)建、綁定流程分析(三)
2011年08月01日 星期一 22:11

net_dev_init中通過open_softirq(NET_RX_SOFTIRQ, net_rx_action);注冊(cè)了軟中斷處理函數(shù),napi調(diào)度中激發(fā)了軟中斷調(diào)用net_rx_action

static void net_rx_action(struct softirq_action *h)

{

       struct list_head *list = &__get_cpu_var(softnet_data).poll_list;

       unsigned long start_time = jiffies;

       int budget = netdev_budget;

       void *have;

 

       local_irq_disable();

 

       while (!list_empty(list)) {

              struct napi_struct *n;

              int work, weight;

 

              /* If softirq window is exhuasted then punt.

               *

               * Note that this is a slight policy change from the

               * previous NAPI code, which would allow up to 2

               * jiffies to pass before breaking out.  The test

               * used to be "jiffies - start_time > 1".

               */

              if (unlikely(budget <= 0 || jiffies != start_time))

                     goto softnet_break;

 

              local_irq_enable();

 

              /* Even though interrupts have been re-enabled, this

               * access is safe because interrupts can only add new

               * entries to the tail of this list, and only ->poll()

               * calls can remove this head entry from the list.

               */

              n = list_entry(list->next, struct napi_struct, poll_list);

 

              have = netpoll_poll_lock(n);

        //weight 每次輪詢最大數(shù)量

              weight = n->weight;

 

              /* This NAPI_STATE_SCHED test is for avoiding a race

               * with netpoll's poll_napi().  Only the entity which

               * obtains the lock and sees NAPI_STATE_SCHED set will

               * actually make the ->poll() call.  Therefore we avoid

               * accidently calling ->poll() when NAPI is not scheduled.

               */

              work = 0;

              if (test_bit(NAPI_STATE_SCHED, &n->state)) //napi的狀態(tài)是否為NAPI_STATE_SCHED

                     work = n->poll(n, weight);             //執(zhí)行輪詢,,輪詢函數(shù)初始化是在net_dev_init中:

                                              //queue->backlog.poll = process_backlog;(默認(rèn))

              WARN_ON_ONCE(work > weight);

 

              budget -= work;

 

              local_irq_disable();

 

              /* Drivers must not modify the NAPI state if they

               * consume the entire weight.  In such cases this code

               * still "owns" the NAPI instance and therefore can

               * move the instance around on the list at-will.

               */

              if (unlikely(work == weight)) {

                     if (unlikely(napi_disable_pending(n)))

                            __napi_complete(n);

                     else

                            list_move_tail(&n->poll_list, list);

              }

 

              netpoll_poll_unlock(have);

       }

out:

       local_irq_enable();

,。。,。,。。,。,。。,。,。。,。,。,。,。。,。,。。,。,。。,。,。。,。,。。,。,。。,。,。。,。,。。。,。,。。,。,。。,。,。。,。

}

 

static int process_backlog(struct napi_struct *napi, int quota)

{

       int work = 0;

       struct softnet_data *queue = &__get_cpu_var(softnet_data);

       unsigned long start_time = jiffies;

 

       napi->weight = weight_p;

       do {

              struct sk_buff *skb;

 

              local_irq_disable();

              skb = __skb_dequeue(&queue->input_pkt_queue);

              if (!skb) {

                     __napi_complete(napi);  //poll隊(duì)列中刪除napi

                     local_irq_enable();

                     break;

              }

              local_irq_enable();

 

              netif_receive_skb(skb);

       } while (++work < quota && jiffies == start_time);

 

       return work;

}

netif_receive_skb中,,會(huì)輪詢ptype_all list找到與packet_bind中協(xié)議類型相符的packet_type,然后通過deliver_skb調(diào)用packet type所注冊(cè)的接收處理函數(shù),。

static inline int deliver_skb(struct sk_buff *skb,

                           struct packet_type *pt_prev,

                           struct net_device *orig_dev)

{

       atomic_inc(&skb->users);

       return pt_prev->func(skb, skb->dev, pt_prev, orig_dev);   //packet_create時(shí)初始化func指向packet_rcv

}

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多