diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 254521319150e5cb74541a3973434497900dc8d5..b69f8762b33958a5ae04480f88d59b903bbf8716 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -10824,38 +10824,36 @@ do { \ int bnx2x_init_firmware(struct bnx2x *bp) { + const char *fw_file_name; struct bnx2x_fw_file_hdr *fw_hdr; int rc; + if (bp->firmware) + return 0; - if (!bp->firmware) { - const char *fw_file_name; - - if (CHIP_IS_E1(bp)) - fw_file_name = FW_FILE_NAME_E1; - else if (CHIP_IS_E1H(bp)) - fw_file_name = FW_FILE_NAME_E1H; - else if (!CHIP_IS_E1x(bp)) - fw_file_name = FW_FILE_NAME_E2; - else { - BNX2X_ERR("Unsupported chip revision\n"); - return -EINVAL; - } - BNX2X_DEV_INFO("Loading %s\n", fw_file_name); + if (CHIP_IS_E1(bp)) + fw_file_name = FW_FILE_NAME_E1; + else if (CHIP_IS_E1H(bp)) + fw_file_name = FW_FILE_NAME_E1H; + else if (!CHIP_IS_E1x(bp)) + fw_file_name = FW_FILE_NAME_E2; + else { + BNX2X_ERR("Unsupported chip revision\n"); + return -EINVAL; + } + BNX2X_DEV_INFO("Loading %s\n", fw_file_name); - rc = request_firmware(&bp->firmware, fw_file_name, - &bp->pdev->dev); - if (rc) { - BNX2X_ERR("Can't load firmware file %s\n", - fw_file_name); - goto request_firmware_exit; - } + rc = request_firmware(&bp->firmware, fw_file_name, &bp->pdev->dev); + if (rc) { + BNX2X_ERR("Can't load firmware file %s\n", + fw_file_name); + goto request_firmware_exit; + } - rc = bnx2x_check_firmware(bp); - if (rc) { - BNX2X_ERR("Corrupt firmware file %s\n", fw_file_name); - goto request_firmware_exit; - } + rc = bnx2x_check_firmware(bp); + if (rc) { + BNX2X_ERR("Corrupt firmware file %s\n", fw_file_name); + goto request_firmware_exit; } fw_hdr = (struct bnx2x_fw_file_hdr *)bp->firmware->data; @@ -10901,6 +10899,7 @@ int bnx2x_init_firmware(struct bnx2x *bp) kfree(bp->init_data); request_firmware_exit: release_firmware(bp->firmware); + bp->firmware = NULL; return rc; } diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index bf01841bda5bb78e1e8378480d98d948541c9c3c..610860f28968a4460aaa63d5004cd69d668216aa 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -166,7 +166,7 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) dev_kfree_skb(skb); net->stats.tx_dropped++; - return NETDEV_TX_BUSY; + return NETDEV_TX_OK; } packet->extension = (void *)(unsigned long)packet + @@ -226,7 +226,7 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) dev_kfree_skb_any(skb); } - return ret ? NETDEV_TX_BUSY : NETDEV_TX_OK; + return NETDEV_TX_OK; } /* diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 81b96e303757a5bd99177b2a0f8b163cec4eb9c7..59681f01a54eb94c5caf3b0edeeca61b9c0ad7e4 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -328,13 +328,13 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) unsigned long lockflags; size_t size = dev->rx_urb_size; - if ((skb = alloc_skb (size + NET_IP_ALIGN, flags)) == NULL) { + skb = __netdev_alloc_skb_ip_align(dev->net, size, flags); + if (!skb) { netif_dbg(dev, rx_err, dev->net, "no rx skb\n"); usbnet_defer_kevent (dev, EVENT_RX_MEMORY); usb_free_urb (urb); return -ENOMEM; } - skb_reserve (skb, NET_IP_ALIGN); entry = (struct skb_data *) skb->cb; entry->urb = urb; diff --git a/drivers/net/wimax/i2400m/netdev.c b/drivers/net/wimax/i2400m/netdev.c index 64a110604ad3d19213102d13f86a75d2ed2dedba..63e4b709efa956b100626e3fc56bd248f4a7828f 100644 --- a/drivers/net/wimax/i2400m/netdev.c +++ b/drivers/net/wimax/i2400m/netdev.c @@ -367,38 +367,28 @@ netdev_tx_t i2400m_hard_start_xmit(struct sk_buff *skb, { struct i2400m *i2400m = net_dev_to_i2400m(net_dev); struct device *dev = i2400m_dev(i2400m); - int result; + int result = -1; d_fnstart(3, dev, "(skb %p net_dev %p)\n", skb, net_dev); - if (skb_header_cloned(skb)) { - /* - * Make tcpdump/wireshark happy -- if they are - * running, the skb is cloned and we will overwrite - * the mac fields in i2400m_tx_prep_header. Expand - * seems to fix this... - */ - result = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); - if (result) { - result = NETDEV_TX_BUSY; - goto error_expand; - } - } + + if (skb_header_cloned(skb) && + pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) + goto drop; if (i2400m->state == I2400M_SS_IDLE) result = i2400m_net_wake_tx(i2400m, net_dev, skb); else result = i2400m_net_tx(i2400m, net_dev, skb); - if (result < 0) + if (result < 0) { +drop: net_dev->stats.tx_dropped++; - else { + } else { net_dev->stats.tx_packets++; net_dev->stats.tx_bytes += skb->len; } - result = NETDEV_TX_OK; -error_expand: - kfree_skb(skb); + dev_kfree_skb(skb); d_fnend(3, dev, "(skb %p net_dev %p) = %d\n", skb, net_dev, result); - return result; + return NETDEV_TX_OK; } diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index b853f06cc14874759e303041426b6adc14e19abc..16c33e308121da59c61629a13fa239dada189874 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -257,7 +257,6 @@ static struct inet6_dev *ip6_mc_find_dev_rcu(struct net *net, if (rt) { dev = rt->dst.dev; - dev_hold(dev); dst_release(&rt->dst); } } else diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 8c2e3ab58f2af211c04f17c337929bd2802cbe27..22b766407de15f95c6ab87621b61cc8936a3505a 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1077,7 +1077,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, struct net *net = dev_net(dev); if (unlikely(!idev)) - return NULL; + return ERR_PTR(-ENODEV); rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, dev, 0); if (unlikely(!rt)) { diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 10687692831eb5f5f097568f0d292fa530c796f1..b49da6c925b3a21ab4f0705cd5262a5f93e72f6b 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -943,20 +943,21 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, } } - if (nf_conntrack_event_report(IPCT_DESTROY, ct, - NETLINK_CB(skb).pid, - nlmsg_report(nlh)) < 0) { + if (del_timer(&ct->timeout)) { + if (nf_conntrack_event_report(IPCT_DESTROY, ct, + NETLINK_CB(skb).pid, + nlmsg_report(nlh)) < 0) { + nf_ct_delete_from_lists(ct); + /* we failed to report the event, try later */ + nf_ct_insert_dying_list(ct); + nf_ct_put(ct); + return 0; + } + /* death_by_timeout would report the event again */ + set_bit(IPS_DYING_BIT, &ct->status); nf_ct_delete_from_lists(ct); - /* we failed to report the event, try later */ - nf_ct_insert_dying_list(ct); nf_ct_put(ct); - return 0; } - - /* death_by_timeout would report the event again */ - set_bit(IPS_DYING_BIT, &ct->status); - - nf_ct_kill(ct); nf_ct_put(ct); return 0; diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 60d47180f0432e0d65c92ef5a6f6cf865b29a3c0..02a21abea65e20c207fe77d81f0240957c259970 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -469,11 +469,15 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) if (slot->qlen == 1) { /* The flow is new */ if (q->tail == NULL) { /* It is the first flow */ slot->next = x; - q->tail = slot; } else { slot->next = q->tail->next; q->tail->next = x; } + /* We put this flow at the end of our flow list. + * This might sound unfair for a new flow to wait after old ones, + * but we could endup servicing new flows only, and freeze old ones. + */ + q->tail = slot; /* We could use a bigger initial quantum for new flows */ slot->allot = q->scaled_quantum; }