From 86c2c0a8a4965ae5cbc0ff97ed39a4472e8e9b23 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sat, 6 Nov 2010 20:11:38 +0000 Subject: [PATCH 01/12] NET: pktgen - fix compile warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This should fix the following warning: net/core/pktgen.c: In function ‘pktgen_if_write’: net/core/pktgen.c:890: warning: comparison of distinct pointer types lacks a cast Signed-off-by: Dmitry Torokhov Reviewed-by: Nelson Elhage Signed-off-by: David S. Miller --- net/core/pktgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/pktgen.c b/net/core/pktgen.c index fbce4b05a53..1992cd050e2 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -887,7 +887,7 @@ static ssize_t pktgen_if_write(struct file *file, i += len; if (debug) { - size_t copy = min(count, 1023); + size_t copy = min_t(size_t, count, 1023); char tb[copy + 1]; if (copy_from_user(tb, user_buffer, copy)) return -EFAULT; From 43b81f85ebfbed9c720f3c27ec7f364930aa3b5e Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sun, 7 Nov 2010 19:58:05 -0800 Subject: [PATCH 02/12] net dst: need linux/cache.h for ____cacheline_aligned_in_smp. Presently the b43legacy build fails on an sh randconfig: In file included from include/net/dst.h:12, from drivers/net/wireless/b43legacy/xmit.c:32: include/net/dst_ops.h:28: error: expected ':', ',', ';', '}' or '__attribute__' before '____cacheline_aligned_in_smp' include/net/dst_ops.h: In function 'dst_entries_get_fast': include/net/dst_ops.h:33: error: 'struct dst_ops' has no member named 'pcpuc_entries' include/net/dst_ops.h: In function 'dst_entries_get_slow': include/net/dst_ops.h:41: error: 'struct dst_ops' has no member named 'pcpuc_entries' include/net/dst_ops.h: In function 'dst_entries_add': include/net/dst_ops.h:49: error: 'struct dst_ops' has no member named 'pcpuc_entries' include/net/dst_ops.h: In function 'dst_entries_init': include/net/dst_ops.h:55: error: 'struct dst_ops' has no member named 'pcpuc_entries' include/net/dst_ops.h: In function 'dst_entries_destroy': include/net/dst_ops.h:60: error: 'struct dst_ops' has no member named 'pcpuc_entries' make[5]: *** [drivers/net/wireless/b43legacy/xmit.o] Error 1 make[5]: *** Waiting for unfinished jobs.... Signed-off-by: Paul Mundt Signed-off-by: David S. Miller --- include/net/dst_ops.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/net/dst_ops.h b/include/net/dst_ops.h index 1fa5306e3e2..51665b3461b 100644 --- a/include/net/dst_ops.h +++ b/include/net/dst_ops.h @@ -2,6 +2,7 @@ #define _NET_DST_OPS_H #include #include +#include struct dst_entry; struct kmem_cachep; From 1a4ec46a68292515ae84deb8ee5cc2572db1fa99 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 1 Nov 2010 10:34:29 +0000 Subject: [PATCH 03/12] solos: Add 'Firmware' attribute for Traverse overall firmware version The existing 'FirmwareVersion' attribute only covers the DSP firmware as provided by Conexant; not the overall version of the device firmware. We do want to be able to see the full version number too. Signed-off-by: David Woodhouse Signed-off-by: David S. Miller --- drivers/atm/solos-attrlist.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/atm/solos-attrlist.c b/drivers/atm/solos-attrlist.c index 1a9332e4efe..9a676ee3082 100644 --- a/drivers/atm/solos-attrlist.c +++ b/drivers/atm/solos-attrlist.c @@ -1,6 +1,7 @@ SOLOS_ATTR_RO(DriverVersion) SOLOS_ATTR_RO(APIVersion) SOLOS_ATTR_RO(FirmwareVersion) +SOLOS_ATTR_RO(Version) // SOLOS_ATTR_RO(DspVersion) // SOLOS_ATTR_RO(CommonHandshake) SOLOS_ATTR_RO(Connected) From 3ce1227c3c374c742ed78484226e24567f09ff99 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 1 Nov 2010 10:35:28 +0000 Subject: [PATCH 04/12] solos: Refuse to upgrade firmware with older FPGA. It doesn't work. Signed-off-by: David Woodhouse Signed-off-by: David S. Miller --- drivers/atm/solos-pci.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index f46138ab38b..2e08c996fd3 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c @@ -1161,6 +1161,14 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) dev_info(&dev->dev, "Solos FPGA Version %d.%02d svn-%d\n", major_ver, minor_ver, fpga_ver); + if (fpga_ver < 37 && (fpga_upgrade || firmware_upgrade || + db_fpga_upgrade || db_firmware_upgrade)) { + dev_warn(&dev->dev, + "FPGA too old; cannot upgrade flash. Use JTAG.\n"); + fpga_upgrade = firmware_upgrade = 0; + db_fpga_upgrade = db_firmware_upgrade = 0; + } + if (card->fpga_version >= DMA_SUPPORTED){ card->using_dma = 1; } else { From 4c46ee52589a4edd67447214eb489b10fed5c53a Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Thu, 4 Nov 2010 11:47:04 +0000 Subject: [PATCH 05/12] classifier: report statistics for basic classifier The basic classifier keeps statistics but does not report it to user space. This showed up when using basic classifier (with police) as a default catch all on ingress; no statistics were reported. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/sched/cls_basic.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c index efd4f95fd05..f23d9155b1e 100644 --- a/net/sched/cls_basic.c +++ b/net/sched/cls_basic.c @@ -268,6 +268,10 @@ static int basic_dump(struct tcf_proto *tp, unsigned long fh, goto nla_put_failure; nla_nest_end(skb, nest); + + if (tcf_exts_dump_stats(skb, &f->exts, &basic_ext_map) < 0) + goto nla_put_failure; + return skb->len; nla_put_failure: From f46421416fb6b91513fb687d6503142cd99034a5 Mon Sep 17 00:00:00 2001 From: Shan Wei Date: Fri, 5 Nov 2010 01:56:34 +0000 Subject: [PATCH 06/12] ipv6: fix overlap check for fragments The type of FRAG6_CB(prev)->offset is int, skb->len is *unsigned* int, and offset is int. Without this patch, type conversion occurred to this expression, when (FRAG6_CB(prev)->offset + prev->len) is less than offset. Signed-off-by: Shan Wei Signed-off-by: David S. Miller --- net/ipv6/reassembly.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index c7ba3149633..0f276645375 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -349,7 +349,7 @@ found: /* Check for overlap with preceding fragment. */ if (prev && - (FRAG6_CB(prev)->offset + prev->len) - offset > 0) + (FRAG6_CB(prev)->offset + prev->len) > offset) goto discard_fq; /* Look for overlap with succeeding segment. */ From 63f4e1903ae41b4e457dd4490afe0f59e7641ad6 Mon Sep 17 00:00:00 2001 From: Guillaume Chazarain Date: Sat, 6 Nov 2010 06:39:31 +0000 Subject: [PATCH 07/12] skge: Remove tx queue stopping in skge_devinit() After e6484930d7c73d324bccda7d43d131088da697b9: net: allocate tx queues in register_netdevice It causes an Oops at skge_probe() time. Signed-off-by: Guillaume Chazarain Signed-off-by: David S. Miller --- drivers/net/skge.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/skge.c b/drivers/net/skge.c index bfec2e0f527..220e0398f1d 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -3858,7 +3858,6 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, /* device is off until link detection */ netif_carrier_off(dev); - netif_stop_queue(dev); return dev; } From 18543a643fae694982c7d89c22436885f3506497 Mon Sep 17 00:00:00 2001 From: Guillaume Chazarain Date: Sat, 6 Nov 2010 06:39:32 +0000 Subject: [PATCH 08/12] net: Detect and ignore netif_stop_queue() calls before register_netdev() After e6484930d7c73d324bccda7d43d131088da697b9: net: allocate tx queues in register_netdevice These calls make net drivers oops at load time, so let's avoid people git-bisect'ing known problems. Signed-off-by: Guillaume Chazarain Signed-off-by: David S. Miller --- include/linux/netdevice.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 072652d94d9..d8fd2c23a1b 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1554,6 +1554,11 @@ static inline void netif_tx_wake_all_queues(struct net_device *dev) static inline void netif_tx_stop_queue(struct netdev_queue *dev_queue) { + if (WARN_ON(!dev_queue)) { + printk(KERN_INFO "netif_stop_queue() cannot be called before " + "register_netdev()"); + return; + } set_bit(__QUEUE_STATE_XOFF, &dev_queue->state); } From eb589063ed482f5592b1378e4136d6998419af6e Mon Sep 17 00:00:00 2001 From: Junchang Wang Date: Sun, 7 Nov 2010 23:19:43 +0000 Subject: [PATCH 09/12] pktgen: correct uninitialized queue_map This fix a bug reported by backyes. Right the first time pktgen's using queue_map that's not been initialized by set_cur_queue_map(pkt_dev); Signed-off-by: Junchang Wang Signed-off-by: Backyes Signed-off-by: David S. Miller --- net/core/pktgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 1992cd050e2..33bc3823ac6 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -2612,8 +2612,8 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, /* Update any of the values, used when we're incrementing various * fields. */ - queue_map = pkt_dev->cur_queue_map; mod_cur_headers(pkt_dev); + queue_map = pkt_dev->cur_queue_map; datalen = (odev->hard_header_len + 16) & ~0xf; @@ -2976,8 +2976,8 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, /* Update any of the values, used when we're incrementing various * fields. */ - queue_map = pkt_dev->cur_queue_map; mod_cur_headers(pkt_dev); + queue_map = pkt_dev->cur_queue_map; skb = __netdev_alloc_skb(odev, pkt_dev->cur_pkt_size + 64 From b67d801f922b989e6756579438bd493ad9052bca Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Mon, 8 Nov 2010 03:03:48 +0000 Subject: [PATCH 10/12] qeth: remove dev_queue_xmit invocation For a certain Hipersockets specific error code in the xmit path, the qeth driver tries to invoke dev_queue_xmit again. Commit 79640a4ca6955e3ebdb7038508fa7a0cd7fa5527 introduces a busylock causing locking problems in case of re-invoked dev_queue_xmit by qeth. This patch removes the attempts to retry packet sending with dev_queue_xmit from the qeth driver. Signed-off-by: Ursula Braun Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 9 ------ drivers/s390/net/qeth_core_main.c | 53 +++++-------------------------- 2 files changed, 8 insertions(+), 54 deletions(-) diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 6be43eb126b..f47a714538d 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -440,7 +440,6 @@ struct qeth_qdio_out_q { * index of buffer to be filled by driver; state EMPTY or PACKING */ int next_buf_to_fill; - int sync_iqdio_error; /* * number of buffers that are currently filled (PRIMED) * -> these buffers are hardware-owned @@ -695,14 +694,6 @@ struct qeth_mc_mac { int is_vmac; }; -struct qeth_skb_data { - __u32 magic; - int count; -}; - -#define QETH_SKB_MAGIC 0x71657468 -#define QETH_SIGA_CC2_RETRIES 3 - struct qeth_rx { int b_count; int b_index; diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 76426706260..09ab6a2d3e4 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -877,8 +877,8 @@ out: return; } -static void __qeth_clear_output_buffer(struct qeth_qdio_out_q *queue, - struct qeth_qdio_out_buffer *buf, unsigned int qeth_skip_skb) +static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue, + struct qeth_qdio_out_buffer *buf) { int i; struct sk_buff *skb; @@ -887,13 +887,11 @@ static void __qeth_clear_output_buffer(struct qeth_qdio_out_q *queue, if (buf->buffer->element[0].flags & 0x40) atomic_dec(&queue->set_pci_flags_count); - if (!qeth_skip_skb) { + skb = skb_dequeue(&buf->skb_list); + while (skb) { + atomic_dec(&skb->users); + dev_kfree_skb_any(skb); skb = skb_dequeue(&buf->skb_list); - while (skb) { - atomic_dec(&skb->users); - dev_kfree_skb_any(skb); - skb = skb_dequeue(&buf->skb_list); - } } for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(queue->card); ++i) { if (buf->buffer->element[i].addr && buf->is_header[i]) @@ -909,12 +907,6 @@ static void __qeth_clear_output_buffer(struct qeth_qdio_out_q *queue, atomic_set(&buf->state, QETH_QDIO_BUF_EMPTY); } -static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue, - struct qeth_qdio_out_buffer *buf) -{ - __qeth_clear_output_buffer(queue, buf, 0); -} - void qeth_clear_qdio_buffers(struct qeth_card *card) { int i, j; @@ -2833,7 +2825,6 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index, } } - queue->sync_iqdio_error = 0; queue->card->dev->trans_start = jiffies; if (queue->card->options.performance_stats) { queue->card->perf_stats.outbound_do_qdio_cnt++; @@ -2849,10 +2840,6 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index, queue->card->perf_stats.outbound_do_qdio_time += qeth_get_micros() - queue->card->perf_stats.outbound_do_qdio_start_time; - if (rc > 0) { - if (!(rc & QDIO_ERROR_SIGA_BUSY)) - queue->sync_iqdio_error = rc & 3; - } if (rc) { queue->card->stats.tx_errors += count; /* ignore temporary SIGA errors without busy condition */ @@ -2940,7 +2927,6 @@ void qeth_qdio_output_handler(struct ccw_device *ccwdev, struct qeth_qdio_out_q *queue = card->qdio.out_qs[__queue]; struct qeth_qdio_out_buffer *buffer; int i; - unsigned qeth_send_err; QETH_CARD_TEXT(card, 6, "qdouhdl"); if (qdio_error & QDIO_ERROR_ACTIVATE_CHECK_CONDITION) { @@ -2956,9 +2942,8 @@ void qeth_qdio_output_handler(struct ccw_device *ccwdev, } for (i = first_element; i < (first_element + count); ++i) { buffer = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q]; - qeth_send_err = qeth_handle_send_error(card, buffer, qdio_error); - __qeth_clear_output_buffer(queue, buffer, - (qeth_send_err == QETH_SEND_ERROR_RETRY) ? 1 : 0); + qeth_handle_send_error(card, buffer, qdio_error); + qeth_clear_output_buffer(queue, buffer); } atomic_sub(count, &queue->used_buffers); /* check if we need to do something on this outbound queue */ @@ -3183,10 +3168,7 @@ int qeth_do_send_packet_fast(struct qeth_card *card, int offset, int hd_len) { struct qeth_qdio_out_buffer *buffer; - struct sk_buff *skb1; - struct qeth_skb_data *retry_ctrl; int index; - int rc; /* spin until we get the queue ... */ while (atomic_cmpxchg(&queue->state, QETH_OUT_Q_UNLOCKED, @@ -3205,25 +3187,6 @@ int qeth_do_send_packet_fast(struct qeth_card *card, atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED); qeth_fill_buffer(queue, buffer, skb, hdr, offset, hd_len); qeth_flush_buffers(queue, index, 1); - if (queue->sync_iqdio_error == 2) { - skb1 = skb_dequeue(&buffer->skb_list); - while (skb1) { - atomic_dec(&skb1->users); - skb1 = skb_dequeue(&buffer->skb_list); - } - retry_ctrl = (struct qeth_skb_data *) &skb->cb[16]; - if (retry_ctrl->magic != QETH_SKB_MAGIC) { - retry_ctrl->magic = QETH_SKB_MAGIC; - retry_ctrl->count = 0; - } - if (retry_ctrl->count < QETH_SIGA_CC2_RETRIES) { - retry_ctrl->count++; - rc = dev_queue_xmit(skb); - } else { - dev_kfree_skb_any(skb); - QETH_CARD_TEXT(card, 2, "qrdrop"); - } - } return 0; out: atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED); From 0cffef48ebf5060f749d8b04ab0437a4ba009e77 Mon Sep 17 00:00:00 2001 From: Frank Blaschka Date: Mon, 8 Nov 2010 03:03:49 +0000 Subject: [PATCH 11/12] qeth: fix race condition during device startup QDIO is running independent from netdevice state. We are not allowed to schedule NAPI in case the netdevice is not open. Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 09ab6a2d3e4..e6b2df0e73f 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -2903,7 +2903,7 @@ void qeth_qdio_start_poll(struct ccw_device *ccwdev, int queue, { struct qeth_card *card = (struct qeth_card *)card_ptr; - if (card->dev) + if (card->dev && (card->dev->flags & IFF_UP)) napi_schedule(&card->napi); } EXPORT_SYMBOL_GPL(qeth_qdio_start_poll); From aa58163a76a3aef33c7220931543d45d0fe43753 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Mon, 8 Nov 2010 06:20:50 +0000 Subject: [PATCH 12/12] rds: Fix rds message leak in rds_message_map_pages The sgs allocation error path leaks the allocated message. Signed-off-by: Pavel Emelyanov Acked-by: Andy Grover Signed-off-by: David S. Miller --- net/rds/message.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/rds/message.c b/net/rds/message.c index 848cff45183..1fd3d29023d 100644 --- a/net/rds/message.c +++ b/net/rds/message.c @@ -249,8 +249,10 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in rm->m_inc.i_hdr.h_len = cpu_to_be32(total_len); rm->data.op_nents = ceil(total_len, PAGE_SIZE); rm->data.op_sg = rds_message_alloc_sgs(rm, num_sgs); - if (!rm->data.op_sg) + if (!rm->data.op_sg) { + rds_message_put(rm); return ERR_PTR(-ENOMEM); + } for (i = 0; i < rm->data.op_nents; ++i) { sg_set_page(&rm->data.op_sg[i],