]> err.no Git - linux-2.6/blobdiff - net/core/dev.c
net: use software GSO for SG+CSUM capable netdevices
[linux-2.6] / net / core / dev.c
index 8d13a9b9f1df66a51daf0aefe71a6a854ea47095..cbf80098980cc381f258747252dc3ccf178d89f7 100644 (file)
@@ -1796,7 +1796,7 @@ gso:
        skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_EGRESS);
 #endif
        if (q->enqueue) {
-               spinlock_t *root_lock = qdisc_root_lock(q);
+               spinlock_t *root_lock = qdisc_lock(q);
 
                spin_lock(root_lock);
 
@@ -1995,7 +1995,7 @@ static void net_tx_action(struct softirq_action *h)
                        smp_mb__before_clear_bit();
                        clear_bit(__QDISC_STATE_SCHED, &q->state);
 
-                       root_lock = qdisc_root_lock(q);
+                       root_lock = qdisc_lock(q);
                        if (spin_trylock(root_lock)) {
                                qdisc_run(q);
                                spin_unlock(root_lock);
@@ -2100,7 +2100,7 @@ static int ing_filter(struct sk_buff *skb)
        rxq = &dev->rx_queue;
 
        q = rxq->qdisc;
-       if (q) {
+       if (q != &noop_qdisc) {
                spin_lock(qdisc_lock(q));
                result = qdisc_enqueue_root(skb, q);
                spin_unlock(qdisc_lock(q));
@@ -2113,7 +2113,7 @@ static inline struct sk_buff *handle_ing(struct sk_buff *skb,
                                         struct packet_type **pt_prev,
                                         int *ret, struct net_device *orig_dev)
 {
-       if (!skb->dev->rx_queue.qdisc)
+       if (skb->dev->rx_queue.qdisc == &noop_qdisc)
                goto out;
 
        if (*pt_prev) {
@@ -3988,6 +3988,10 @@ int register_netdevice(struct net_device *dev)
                }
        }
 
+       /* Enable software GSO if SG is supported. */
+       if (dev->features & NETIF_F_SG)
+               dev->features |= NETIF_F_GSO;
+
        netdev_initialize_kobject(dev);
        ret = netdev_register_kobject(dev);
        if (ret)
@@ -4200,6 +4204,7 @@ static void netdev_init_queues(struct net_device *dev)
 {
        netdev_init_one_queue(dev, &dev->rx_queue, NULL);
        netdev_for_each_tx_queue(dev, netdev_init_one_queue, NULL);
+       spin_lock_init(&dev->tx_global_lock);
 }
 
 /**