aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorFrank Pavlic <fpavlic@de.ibm.com>2006-09-15 10:26:19 -0400
committerJeff Garzik <jeff@garzik.org>2006-09-17 01:03:07 -0400
commitf7b65d70a3e6f1c97eb614964270816992d0d4b4 (patch)
treefae68b2d6c215abacd3074b81bc320f5b3e3a0e0 /drivers
parent1fda1a120b7dcddf382ad105b4783a69e81c7a2b (diff)
[PATCH] s390: qeth driver fixes [3/6]
[PATCH 6/9] s390: qeth driver fixes [3/6] From: Frank Pavlic <fpavlic@de.ibm.com> fixed kernel panic caused by qeth driver: Using a bonding device qeth driver will realloc headroom for every skb coming from the bond device. Once this happens qeth frees the original skb and set the skb pointer to the new realloced skb. Under heavy transmit workload (e.g.UDP streams) through bond network device the qdio output queue might get full. In this case we return with EBUSY from qeth_send_packet. Returning to qeth_hard_start_xmit routine the skb address on the stack still points to the old address, which has been freed before. Returning from qeth_hard_start_xmit with EBUSY results in requeuing the skb. In this case it corrupts the qdisc queue and results in kernel panic. Signed-off-by: Frank Pavlic <fpavlic@de.ibm.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/s390/net/qeth.h35
-rw-r--r--drivers/s390/net/qeth_main.c193
-rw-r--r--drivers/s390/net/qeth_tso.h2
3 files changed, 114 insertions, 116 deletions
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h
index e8bd8c5ced1f..c04ee915dc1b 100644
--- a/drivers/s390/net/qeth.h
+++ b/drivers/s390/net/qeth.h
@@ -859,23 +859,18 @@ qeth_get_ipa_adp_type(enum qeth_link_types link_type)
859 } 859 }
860} 860}
861 861
862static inline int 862static inline struct sk_buff *
863qeth_realloc_headroom(struct qeth_card *card, struct sk_buff **skb, int size) 863qeth_realloc_headroom(struct qeth_card *card, struct sk_buff *skb, int size)
864{ 864{
865 struct sk_buff *new_skb = NULL; 865 struct sk_buff *new_skb = skb;
866 866
867 if (skb_headroom(*skb) < size){ 867 if (skb_headroom(skb) >= size)
868 new_skb = skb_realloc_headroom(*skb, size); 868 return skb;
869 if (!new_skb) { 869 new_skb = skb_realloc_headroom(skb, size);
870 PRINT_ERR("qeth_prepare_skb: could " 870 if (!new_skb)
871 "not realloc headroom for qeth_hdr " 871 PRINT_ERR("Could not realloc headroom for qeth_hdr "
872 "on interface %s", QETH_CARD_IFNAME(card)); 872 "on interface %s", QETH_CARD_IFNAME(card));
873 return -ENOMEM; 873 return new_skb;
874 }
875 kfree_skb(*skb);
876 *skb = new_skb;
877 }
878 return 0;
879} 874}
880 875
881static inline struct sk_buff * 876static inline struct sk_buff *
@@ -885,16 +880,15 @@ qeth_pskb_unshare(struct sk_buff *skb, int pri)
885 if (!skb_cloned(skb)) 880 if (!skb_cloned(skb))
886 return skb; 881 return skb;
887 nskb = skb_copy(skb, pri); 882 nskb = skb_copy(skb, pri);
888 kfree_skb(skb); /* free our shared copy */
889 return nskb; 883 return nskb;
890} 884}
891 885
892static inline void * 886static inline void *
893qeth_push_skb(struct qeth_card *card, struct sk_buff **skb, int size) 887qeth_push_skb(struct qeth_card *card, struct sk_buff *skb, int size)
894{ 888{
895 void *hdr; 889 void *hdr;
896 890
897 hdr = (void *) skb_push(*skb, size); 891 hdr = (void *) skb_push(skb, size);
898 /* 892 /*
899 * sanity check, the Linux memory allocation scheme should 893 * sanity check, the Linux memory allocation scheme should
900 * never present us cases like this one (the qdio header size plus 894 * never present us cases like this one (the qdio header size plus
@@ -903,8 +897,7 @@ qeth_push_skb(struct qeth_card *card, struct sk_buff **skb, int size)
903 if ((((unsigned long) hdr) & (~(PAGE_SIZE - 1))) != 897 if ((((unsigned long) hdr) & (~(PAGE_SIZE - 1))) !=
904 (((unsigned long) hdr + size + 898 (((unsigned long) hdr + size +
905 QETH_IP_HEADER_SIZE) & (~(PAGE_SIZE - 1)))) { 899 QETH_IP_HEADER_SIZE) & (~(PAGE_SIZE - 1)))) {
906 PRINT_ERR("qeth_prepare_skb: misaligned " 900 PRINT_ERR("Misaligned packet on interface %s. Discarded.",
907 "packet on interface %s. Discarded.",
908 QETH_CARD_IFNAME(card)); 901 QETH_CARD_IFNAME(card));
909 return NULL; 902 return NULL;
910 } 903 }
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index ffff7a12b54d..522fb9dd551e 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -3919,49 +3919,59 @@ qeth_get_ip_version(struct sk_buff *skb)
3919 } 3919 }
3920} 3920}
3921 3921
3922static inline int 3922static inline struct qeth_hdr *
3923qeth_prepare_skb(struct qeth_card *card, struct sk_buff **skb, 3923__qeth_prepare_skb(struct qeth_card *card, struct sk_buff *skb, int ipv)
3924 struct qeth_hdr **hdr, int ipv)
3925{ 3924{
3926 int rc = 0;
3927#ifdef CONFIG_QETH_VLAN 3925#ifdef CONFIG_QETH_VLAN
3928 u16 *tag; 3926 u16 *tag;
3929#endif 3927 if (card->vlangrp && vlan_tx_tag_present(skb) &&
3930
3931 QETH_DBF_TEXT(trace, 6, "prepskb");
3932 if (card->info.type == QETH_CARD_TYPE_OSN) {
3933 *hdr = (struct qeth_hdr *)(*skb)->data;
3934 return rc;
3935 }
3936 rc = qeth_realloc_headroom(card, skb, sizeof(struct qeth_hdr));
3937 if (rc)
3938 return rc;
3939#ifdef CONFIG_QETH_VLAN
3940 if (card->vlangrp && vlan_tx_tag_present(*skb) &&
3941 ((ipv == 6) || card->options.layer2) ) { 3928 ((ipv == 6) || card->options.layer2) ) {
3942 /* 3929 /*
3943 * Move the mac addresses (6 bytes src, 6 bytes dest) 3930 * Move the mac addresses (6 bytes src, 6 bytes dest)
3944 * to the beginning of the new header. We are using three 3931 * to the beginning of the new header. We are using three
3945 * memcpys instead of one memmove to save cycles. 3932 * memcpys instead of one memmove to save cycles.
3946 */ 3933 */
3947 skb_push(*skb, VLAN_HLEN); 3934 skb_push(skb, VLAN_HLEN);
3948 memcpy((*skb)->data, (*skb)->data + 4, 4); 3935 memcpy(skb->data, skb->data + 4, 4);
3949 memcpy((*skb)->data + 4, (*skb)->data + 8, 4); 3936 memcpy(skb->data + 4, skb->data + 8, 4);
3950 memcpy((*skb)->data + 8, (*skb)->data + 12, 4); 3937 memcpy(skb->data + 8, skb->data + 12, 4);
3951 tag = (u16 *)((*skb)->data + 12); 3938 tag = (u16 *)(skb->data + 12);
3952 /* 3939 /*
3953 * first two bytes = ETH_P_8021Q (0x8100) 3940 * first two bytes = ETH_P_8021Q (0x8100)
3954 * second two bytes = VLANID 3941 * second two bytes = VLANID
3955 */ 3942 */
3956 *tag = __constant_htons(ETH_P_8021Q); 3943 *tag = __constant_htons(ETH_P_8021Q);
3957 *(tag + 1) = htons(vlan_tx_tag_get(*skb)); 3944 *(tag + 1) = htons(vlan_tx_tag_get(skb));
3958 } 3945 }
3959#endif 3946#endif
3960 *hdr = (struct qeth_hdr *) 3947 return ((struct qeth_hdr *)
3961 qeth_push_skb(card, skb, sizeof(struct qeth_hdr)); 3948 qeth_push_skb(card, skb, sizeof(struct qeth_hdr)));
3962 if (*hdr == NULL) 3949}
3963 return -EINVAL; 3950
3964 return 0; 3951static inline void
3952__qeth_free_new_skb(struct sk_buff *orig_skb, struct sk_buff *new_skb)
3953{
3954 if (orig_skb != new_skb)
3955 dev_kfree_skb_any(new_skb);
3956}
3957
3958static inline struct sk_buff *
3959qeth_prepare_skb(struct qeth_card *card, struct sk_buff *skb,
3960 struct qeth_hdr **hdr, int ipv)
3961{
3962 struct sk_buff *new_skb;
3963
3964 QETH_DBF_TEXT(trace, 6, "prepskb");
3965
3966 new_skb = qeth_realloc_headroom(card, skb, sizeof(struct qeth_hdr));
3967 if (new_skb == NULL)
3968 return NULL;
3969 *hdr = __qeth_prepare_skb(card, new_skb, ipv);
3970 if (*hdr == NULL) {
3971 __qeth_free_new_skb(skb, new_skb);
3972 return NULL;
3973 }
3974 return new_skb;
3965} 3975}
3966 3976
3967static inline u8 3977static inline u8
@@ -4242,21 +4252,15 @@ qeth_do_send_packet_fast(struct qeth_card *card, struct qeth_qdio_out_q *queue,
4242 * check if buffer is empty to make sure that we do not 'overtake' 4252 * check if buffer is empty to make sure that we do not 'overtake'
4243 * ourselves and try to fill a buffer that is already primed 4253 * ourselves and try to fill a buffer that is already primed
4244 */ 4254 */
4245 if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY) { 4255 if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY)
4246 card->stats.tx_dropped++; 4256 goto out;
4247 atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
4248 return -EBUSY;
4249 }
4250 if (ctx == NULL) 4257 if (ctx == NULL)
4251 queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) % 4258 queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) %
4252 QDIO_MAX_BUFFERS_PER_Q; 4259 QDIO_MAX_BUFFERS_PER_Q;
4253 else { 4260 else {
4254 buffers_needed = qeth_eddp_check_buffers_for_context(queue,ctx); 4261 buffers_needed = qeth_eddp_check_buffers_for_context(queue,ctx);
4255 if (buffers_needed < 0) { 4262 if (buffers_needed < 0)
4256 card->stats.tx_dropped++; 4263 goto out;
4257 atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
4258 return -EBUSY;
4259 }
4260 queue->next_buf_to_fill = 4264 queue->next_buf_to_fill =
4261 (queue->next_buf_to_fill + buffers_needed) % 4265 (queue->next_buf_to_fill + buffers_needed) %
4262 QDIO_MAX_BUFFERS_PER_Q; 4266 QDIO_MAX_BUFFERS_PER_Q;
@@ -4271,6 +4275,9 @@ qeth_do_send_packet_fast(struct qeth_card *card, struct qeth_qdio_out_q *queue,
4271 qeth_flush_buffers(queue, 0, index, flush_cnt); 4275 qeth_flush_buffers(queue, 0, index, flush_cnt);
4272 } 4276 }
4273 return 0; 4277 return 0;
4278out:
4279 atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
4280 return -EBUSY;
4274} 4281}
4275 4282
4276static inline int 4283static inline int
@@ -4296,8 +4303,7 @@ qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
4296 * check if buffer is empty to make sure that we do not 'overtake' 4303 * check if buffer is empty to make sure that we do not 'overtake'
4297 * ourselves and try to fill a buffer that is already primed 4304 * ourselves and try to fill a buffer that is already primed
4298 */ 4305 */
4299 if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY){ 4306 if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY) {
4300 card->stats.tx_dropped++;
4301 atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED); 4307 atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
4302 return -EBUSY; 4308 return -EBUSY;
4303 } 4309 }
@@ -4320,7 +4326,6 @@ qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
4320 * again */ 4326 * again */
4321 if (atomic_read(&buffer->state) != 4327 if (atomic_read(&buffer->state) !=
4322 QETH_QDIO_BUF_EMPTY){ 4328 QETH_QDIO_BUF_EMPTY){
4323 card->stats.tx_dropped++;
4324 qeth_flush_buffers(queue, 0, start_index, flush_count); 4329 qeth_flush_buffers(queue, 0, start_index, flush_count);
4325 atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED); 4330 atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
4326 return -EBUSY; 4331 return -EBUSY;
@@ -4331,7 +4336,6 @@ qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
4331 * free buffers) to handle eddp context */ 4336 * free buffers) to handle eddp context */
4332 if (qeth_eddp_check_buffers_for_context(queue,ctx) < 0){ 4337 if (qeth_eddp_check_buffers_for_context(queue,ctx) < 0){
4333 printk("eddp tx_dropped 1\n"); 4338 printk("eddp tx_dropped 1\n");
4334 card->stats.tx_dropped++;
4335 rc = -EBUSY; 4339 rc = -EBUSY;
4336 goto out; 4340 goto out;
4337 } 4341 }
@@ -4343,7 +4347,6 @@ qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
4343 tmp = qeth_eddp_fill_buffer(queue,ctx,queue->next_buf_to_fill); 4347 tmp = qeth_eddp_fill_buffer(queue,ctx,queue->next_buf_to_fill);
4344 if (tmp < 0) { 4348 if (tmp < 0) {
4345 printk("eddp tx_dropped 2\n"); 4349 printk("eddp tx_dropped 2\n");
4346 card->stats.tx_dropped++;
4347 rc = - EBUSY; 4350 rc = - EBUSY;
4348 goto out; 4351 goto out;
4349 } 4352 }
@@ -4391,21 +4394,21 @@ qeth_get_elements_no(struct qeth_card *card, void *hdr,
4391{ 4394{
4392 int elements_needed = 0; 4395 int elements_needed = 0;
4393 4396
4394 if (skb_shinfo(skb)->nr_frags > 0) { 4397 if (skb_shinfo(skb)->nr_frags > 0)
4395 elements_needed = (skb_shinfo(skb)->nr_frags + 1); 4398 elements_needed = (skb_shinfo(skb)->nr_frags + 1);
4396 } 4399 if (elements_needed == 0)
4397 if (elements_needed == 0 )
4398 elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE) 4400 elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE)
4399 + skb->len) >> PAGE_SHIFT); 4401 + skb->len) >> PAGE_SHIFT);
4400 if ((elements_needed + elems) > QETH_MAX_BUFFER_ELEMENTS(card)){ 4402 if ((elements_needed + elems) > QETH_MAX_BUFFER_ELEMENTS(card)){
4401 PRINT_ERR("qeth_do_send_packet: invalid size of " 4403 PRINT_ERR("Invalid size of IP packet "
4402 "IP packet (Number=%d / Length=%d). Discarded.\n", 4404 "(Number=%d / Length=%d). Discarded.\n",
4403 (elements_needed+elems), skb->len); 4405 (elements_needed+elems), skb->len);
4404 return 0; 4406 return 0;
4405 } 4407 }
4406 return elements_needed; 4408 return elements_needed;
4407} 4409}
4408 4410
4411
4409static inline int 4412static inline int
4410qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) 4413qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
4411{ 4414{
@@ -4421,108 +4424,110 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
4421 unsigned short nr_frags = skb_shinfo(skb)->nr_frags; 4424 unsigned short nr_frags = skb_shinfo(skb)->nr_frags;
4422 unsigned short tso_size = skb_shinfo(skb)->gso_size; 4425 unsigned short tso_size = skb_shinfo(skb)->gso_size;
4423#endif 4426#endif
4427 struct sk_buff *new_skb, *new_skb2;
4424 int rc; 4428 int rc;
4425 4429
4426 QETH_DBF_TEXT(trace, 6, "sendpkt"); 4430 QETH_DBF_TEXT(trace, 6, "sendpkt");
4427 4431
4432 new_skb = skb;
4433 if ((card->info.type == QETH_CARD_TYPE_OSN) &&
4434 (skb->protocol == htons(ETH_P_IPV6)))
4435 return -EPERM;
4436 cast_type = qeth_get_cast_type(card, skb);
4437 if ((cast_type == RTN_BROADCAST) &&
4438 (card->info.broadcast_capable == 0))
4439 return -EPERM;
4440 queue = card->qdio.out_qs
4441 [qeth_get_priority_queue(card, skb, ipv, cast_type)];
4428 if (!card->options.layer2) { 4442 if (!card->options.layer2) {
4429 ipv = qeth_get_ip_version(skb); 4443 ipv = qeth_get_ip_version(skb);
4430 if ((card->dev->hard_header == qeth_fake_header) && ipv) { 4444 if ((card->dev->hard_header == qeth_fake_header) && ipv) {
4431 if ((skb = qeth_pskb_unshare(skb,GFP_ATOMIC)) == NULL) { 4445 new_skb = qeth_pskb_unshare(skb, GFP_ATOMIC);
4432 card->stats.tx_dropped++; 4446 if (!new_skb)
4433 dev_kfree_skb_irq(skb); 4447 return -ENOMEM;
4434 return 0;
4435 }
4436 if(card->dev->type == ARPHRD_IEEE802_TR){ 4448 if(card->dev->type == ARPHRD_IEEE802_TR){
4437 skb_pull(skb, QETH_FAKE_LL_LEN_TR); 4449 skb_pull(new_skb, QETH_FAKE_LL_LEN_TR);
4438 } else { 4450 } else {
4439 skb_pull(skb, QETH_FAKE_LL_LEN_ETH); 4451 skb_pull(new_skb, QETH_FAKE_LL_LEN_ETH);
4440 } 4452 }
4441 } 4453 }
4442 } 4454 }
4443 if ((card->info.type == QETH_CARD_TYPE_OSN) &&
4444 (skb->protocol == htons(ETH_P_IPV6))) {
4445 dev_kfree_skb_any(skb);
4446 return 0;
4447 }
4448 cast_type = qeth_get_cast_type(card, skb);
4449 if ((cast_type == RTN_BROADCAST) &&
4450 (card->info.broadcast_capable == 0)){
4451 card->stats.tx_dropped++;
4452 card->stats.tx_errors++;
4453 dev_kfree_skb_any(skb);
4454 return NETDEV_TX_OK;
4455 }
4456 queue = card->qdio.out_qs
4457 [qeth_get_priority_queue(card, skb, ipv, cast_type)];
4458
4459 if (skb_is_gso(skb)) 4455 if (skb_is_gso(skb))
4460 large_send = card->options.large_send; 4456 large_send = card->options.large_send;
4461 4457 /* check on OSN device*/
4462 /*are we able to do TSO ? If so ,prepare and send it from here */ 4458 if (card->info.type == QETH_CARD_TYPE_OSN)
4459 hdr = (struct qeth_hdr *)new_skb->data;
4460 /*are we able to do TSO ? */
4463 if ((large_send == QETH_LARGE_SEND_TSO) && 4461 if ((large_send == QETH_LARGE_SEND_TSO) &&
4464 (cast_type == RTN_UNSPEC)) { 4462 (cast_type == RTN_UNSPEC)) {
4465 rc = qeth_tso_prepare_packet(card, skb, ipv, cast_type); 4463 rc = qeth_tso_prepare_packet(card, new_skb, ipv, cast_type);
4466 if (rc) { 4464 if (rc) {
4467 card->stats.tx_dropped++; 4465 __qeth_free_new_skb(skb, new_skb);
4468 card->stats.tx_errors++; 4466 return rc;
4469 dev_kfree_skb_any(skb);
4470 return NETDEV_TX_OK;
4471 } 4467 }
4472 elements_needed++; 4468 elements_needed++;
4473 } else { 4469 } else if (card->info.type != QETH_CARD_TYPE_OSN) {
4474 if ((rc = qeth_prepare_skb(card, &skb, &hdr, ipv))) { 4470 new_skb2 = qeth_prepare_skb(card, new_skb, &hdr, ipv);
4475 QETH_DBF_TEXT_(trace, 4, "pskbe%d", rc); 4471 if (!new_skb2) {
4476 return rc; 4472 __qeth_free_new_skb(skb, new_skb);
4473 return -EINVAL;
4477 } 4474 }
4478 if (card->info.type != QETH_CARD_TYPE_OSN) 4475 if (new_skb != skb)
4479 qeth_fill_header(card, hdr, skb, ipv, cast_type); 4476 __qeth_free_new_skb(new_skb2, new_skb);
4477 new_skb = new_skb2;
4478 qeth_fill_header(card, hdr, new_skb, ipv, cast_type);
4480 } 4479 }
4481
4482 if (large_send == QETH_LARGE_SEND_EDDP) { 4480 if (large_send == QETH_LARGE_SEND_EDDP) {
4483 ctx = qeth_eddp_create_context(card, skb, hdr); 4481 ctx = qeth_eddp_create_context(card, new_skb, hdr);
4484 if (ctx == NULL) { 4482 if (ctx == NULL) {
4483 __qeth_free_new_skb(skb, new_skb);
4485 PRINT_WARN("could not create eddp context\n"); 4484 PRINT_WARN("could not create eddp context\n");
4486 return -EINVAL; 4485 return -EINVAL;
4487 } 4486 }
4488 } else { 4487 } else {
4489 int elems = qeth_get_elements_no(card,(void*) hdr, skb, 4488 int elems = qeth_get_elements_no(card,(void*) hdr, new_skb,
4490 elements_needed); 4489 elements_needed);
4491 if (!elems) 4490 if (!elems) {
4491 __qeth_free_new_skb(skb, new_skb);
4492 return -EINVAL; 4492 return -EINVAL;
4493 }
4493 elements_needed += elems; 4494 elements_needed += elems;
4494 } 4495 }
4495 4496
4496 if (card->info.type != QETH_CARD_TYPE_IQD) 4497 if (card->info.type != QETH_CARD_TYPE_IQD)
4497 rc = qeth_do_send_packet(card, queue, skb, hdr, 4498 rc = qeth_do_send_packet(card, queue, new_skb, hdr,
4498 elements_needed, ctx); 4499 elements_needed, ctx);
4499 else 4500 else
4500 rc = qeth_do_send_packet_fast(card, queue, skb, hdr, 4501 rc = qeth_do_send_packet_fast(card, queue, new_skb, hdr,
4501 elements_needed, ctx); 4502 elements_needed, ctx);
4502 if (!rc){ 4503 if (!rc) {
4503 card->stats.tx_packets++; 4504 card->stats.tx_packets++;
4504 card->stats.tx_bytes += tx_bytes; 4505 card->stats.tx_bytes += tx_bytes;
4506 if (new_skb != skb)
4507 dev_kfree_skb_any(skb);
4505#ifdef CONFIG_QETH_PERF_STATS 4508#ifdef CONFIG_QETH_PERF_STATS
4506 if (tso_size && 4509 if (tso_size &&
4507 !(large_send == QETH_LARGE_SEND_NO)) { 4510 !(large_send == QETH_LARGE_SEND_NO)) {
4508 card->perf_stats.large_send_bytes += tx_bytes; 4511 card->perf_stats.large_send_bytes += tx_bytes;
4509 card->perf_stats.large_send_cnt++; 4512 card->perf_stats.large_send_cnt++;
4510 } 4513 }
4511 if (nr_frags > 0){ 4514 if (nr_frags > 0) {
4512 card->perf_stats.sg_skbs_sent++; 4515 card->perf_stats.sg_skbs_sent++;
4513 /* nr_frags + skb->data */ 4516 /* nr_frags + skb->data */
4514 card->perf_stats.sg_frags_sent += 4517 card->perf_stats.sg_frags_sent +=
4515 nr_frags + 1; 4518 nr_frags + 1;
4516 } 4519 }
4517#endif /* CONFIG_QETH_PERF_STATS */ 4520#endif /* CONFIG_QETH_PERF_STATS */
4521 } else {
4522 card->stats.tx_dropped++;
4523 __qeth_free_new_skb(skb, new_skb);
4518 } 4524 }
4519 if (ctx != NULL) { 4525 if (ctx != NULL) {
4520 /* drop creator's reference */ 4526 /* drop creator's reference */
4521 qeth_eddp_put_context(ctx); 4527 qeth_eddp_put_context(ctx);
4522 /* free skb; it's not referenced by a buffer */ 4528 /* free skb; it's not referenced by a buffer */
4523 if (rc == 0) 4529 if (!rc)
4524 dev_kfree_skb_any(skb); 4530 dev_kfree_skb_any(new_skb);
4525
4526 } 4531 }
4527 return rc; 4532 return rc;
4528} 4533}
diff --git a/drivers/s390/net/qeth_tso.h b/drivers/s390/net/qeth_tso.h
index 593f298142c1..14504afb044e 100644
--- a/drivers/s390/net/qeth_tso.h
+++ b/drivers/s390/net/qeth_tso.h
@@ -24,7 +24,7 @@ static inline struct qeth_hdr_tso *
24qeth_tso_prepare_skb(struct qeth_card *card, struct sk_buff **skb) 24qeth_tso_prepare_skb(struct qeth_card *card, struct sk_buff **skb)
25{ 25{
26 QETH_DBF_TEXT(trace, 5, "tsoprsk"); 26 QETH_DBF_TEXT(trace, 5, "tsoprsk");
27 return qeth_push_skb(card, skb, sizeof(struct qeth_hdr_tso)); 27 return qeth_push_skb(card, *skb, sizeof(struct qeth_hdr_tso));
28} 28}
29 29
30/** 30/**