数据收发的软中断以及数据从网卡发送
来源:互联网 发布:消音软件哪个好 编辑:程序博客网 时间:2024/05/16 23:38
注册软中断
static int __init net_dev_init(void){ ...... open_softirq(NET_TX_SOFTIRQ, net_tx_action);open_softirq(NET_RX_SOFTIRQ, net_rx_action); ......}static void net_tx_action(struct softirq_action *h){struct softnet_data *sd = &__get_cpu_var(softnet_data);if (sd->completion_queue) {struct sk_buff *clist;local_irq_disable();clist = sd->completion_queue;sd->completion_queue = NULL;local_irq_enable();while (clist) {struct sk_buff *skb = clist;clist = clist->next;WARN_ON(atomic_read(&skb->users));__kfree_skb(skb);}}if (sd->output_queue) {struct Qdisc *head;local_irq_disable();head = sd->output_queue;sd->output_queue = NULL;local_irq_enable(); //这里不是发送某个网卡的某个包,而是针对所有流控对象Qdisc的调度,逻辑上与网卡没有直接关系while (head) { struct Qdisc *q = head;spinlock_t *root_lock;head = head->next_sched;root_lock = qdisc_lock(q);if (spin_trylock(root_lock)) {smp_mb__before_clear_bit();clear_bit(__QDISC_STATE_SCHED, &q->state);qdisc_run(q);spin_unlock(root_lock);} else {if (!test_bit(__QDISC_STATE_DEACTIVATED, &q->state)) {__netif_reschedule(q);} else {smp_mb__before_clear_bit();clear_bit(__QDISC_STATE_SCHED, &q->state);}}}}}static inline int qdisc_restart(struct Qdisc *q){struct netdev_queue *txq;struct net_device *dev;spinlock_t *root_lock;struct sk_buff *skb;/* Dequeue packet */skb = dequeue_skb(q);if (unlikely(!skb))return 0;root_lock = qdisc_lock(q);dev = qdisc_dev(q);txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));return sch_direct_xmit(skb, q, dev, txq, root_lock);}调用dev_hard_start_xmit将数据包发送出去int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,struct net_device *dev, struct netdev_queue *txq,spinlock_t *root_lock){int ret = NETDEV_TX_BUSY;/* And release qdisc */spin_unlock(root_lock);HARD_TX_LOCK(dev, txq, smp_processor_id());if (!netif_tx_queue_stopped(txq) && !netif_tx_queue_frozen(txq))ret = dev_hard_start_xmit(skb, dev, txq);HARD_TX_UNLOCK(dev, txq);spin_lock(root_lock);switch (ret) {case NETDEV_TX_OK:/* Driver sent out skb successfully */ret = qdisc_qlen(q);break;case NETDEV_TX_LOCKED:/* Driver try lock failed */ret = handle_dev_cpu_collision(skb, txq, q);break;default:/* Driver returned NETDEV_TX_BUSY - requeue skb */if (unlikely (ret != NETDEV_TX_BUSY && net_ratelimit()))printk(KERN_WARNING "BUG %s code %d qlen %d\n", dev->name, ret, q->q.qlen);ret = dev_requeue_skb(skb, q);break;}if (ret && (netif_tx_queue_stopped(txq) ||netif_tx_queue_frozen(txq)))ret = 0;return ret;}int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,struct netdev_queue *txq){const struct net_device_ops *ops = dev->netdev_ops;int rc;if (likely(!skb->next)) {if (!list_empty(&ptype_all))dev_queue_xmit_nit(skb, dev);if (netif_needs_gso(dev, skb)) {if (unlikely(dev_gso_segment(skb)))goto out_kfree_skb;if (skb->next)goto gso;}if (dev->priv_flags & IFF_XMIT_DST_RELEASE)skb_dst_drop(skb);rc = ops->ndo_start_xmit(skb, dev);if (rc == NETDEV_TX_OK)txq_trans_update(txq);return rc;}gso: rc = ops->ndo_start_xmit(skb, dev); }
ndo_start_xmit调用驱动的发送方法将包发出
0 0
- 数据收发的软中断以及数据从网卡发送
- 零拷贝原理-数据的收发-软中断和DMA
- NDIS LWF收发3G网卡Mobile Broadband的自定义数据
- stm32串口中断收发数据环形缓冲区的设计
- stm32串口中断收发数据环形缓冲区的设计
- eCos 网卡数据的发送、接受过程
- 数据报的接收过程详解---从网卡到L3层(非NAPI,即接收数据采用中断方式)
- 数据报的接收过程详解---从网卡到L3层(非NAPI,即接收数据采用中断方式)
- socket通过多网卡收发数据
- STM32 I2C从机发送数据_中断方式
- 【STM32 IIC详解】stm32 IIC从机模式(中断方式收发数据)
- 多网卡指定网卡发送数据
- 网卡只发送不接收数据的快捷处理
- 关于收发数据的问题
- Linux中利用RAW SOCKET直接通过网卡收发数据
- Linux中利用RAW SOCKET直接通过网卡收发数据
- LAN9221网卡驱动分析之一 发送数据
- 网卡如何接受和发送数据
- HDU-5816-Hearthstone-DP+数学推导
- HDU 4422 采蘑菇的小女孩
- group by、having以及order by
- UVA 658 It's not a Bug, it's a Feature! (特殊图最短路)
- [Servlet]Servlet生命周期
- 数据收发的软中断以及数据从网卡发送
- 网页ad广告图下拉定点滑动
- CodeForces 650B(二分)
- Getting Started with the G1 Garbage Collector (待翻译)
- 【Java源码分析】LinkedHashSet和HashSet源码分析
- 安卓面试中遇到的问题记录
- UVa 340 Master-Minds Hints(猜数字游戏的提示)
- 【HDU5156】Harry and Christmas tree,两种离线的做法
- MySQL性能优化的最佳20+条经验