aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/cxgb3/cxgb3_offload.c
diff options
context:
space:
mode:
authorDivy Le Ray <divy@chelsio.com>2009-06-09 19:25:21 -0400
committerDavid S. Miller <davem@davemloft.net>2009-06-11 05:47:13 -0400
commit74b793e1ef79edc49bc031a88d62f1e93fc6b30f (patch)
treedc32a12c1883f882f524e6a79561787aa36cc9ec /drivers/net/cxgb3/cxgb3_offload.c
parent87433bfc75f34599c38137e172b6bf8fd41971ba (diff)
cxgb3: remove __GFP_NOFAIL usage
Pre-allocate a skb at init time to be used for control messages to the HW if skb allocation fails. Tolerate failures to send messages initializing some memories at the cost of parity error detection for these memories. Retry sending connection id release messages if both alloc_skb(GFP_ATOMIC) and alloc_skb(GFP_KERNEL) fail. Do not bring the interface up if messages binding queue set to port fail to be sent. Signed-off-by: Divy Le Ray <divy@chelsio.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/cxgb3/cxgb3_offload.c')
-rw-r--r--drivers/net/cxgb3/cxgb3_offload.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c
index 620d80be6aac..f9f54b57b28c 100644
--- a/drivers/net/cxgb3/cxgb3_offload.c
+++ b/drivers/net/cxgb3/cxgb3_offload.c
@@ -566,13 +566,31 @@ static void t3_process_tid_release_list(struct work_struct *work)
566 spin_unlock_bh(&td->tid_release_lock); 566 spin_unlock_bh(&td->tid_release_lock);
567 567
568 skb = alloc_skb(sizeof(struct cpl_tid_release), 568 skb = alloc_skb(sizeof(struct cpl_tid_release),
569 GFP_KERNEL | __GFP_NOFAIL); 569 GFP_KERNEL);
570 if (!skb)
571 skb = td->nofail_skb;
572 if (!skb) {
573 spin_lock_bh(&td->tid_release_lock);
574 p->ctx = (void *)td->tid_release_list;
575 td->tid_release_list = (struct t3c_tid_entry *)p;
576 break;
577 }
570 mk_tid_release(skb, p - td->tid_maps.tid_tab); 578 mk_tid_release(skb, p - td->tid_maps.tid_tab);
571 cxgb3_ofld_send(tdev, skb); 579 cxgb3_ofld_send(tdev, skb);
572 p->ctx = NULL; 580 p->ctx = NULL;
581 if (skb == td->nofail_skb)
582 td->nofail_skb =
583 alloc_skb(sizeof(struct cpl_tid_release),
584 GFP_KERNEL);
573 spin_lock_bh(&td->tid_release_lock); 585 spin_lock_bh(&td->tid_release_lock);
574 } 586 }
587 td->release_list_incomplete = (td->tid_release_list == NULL) ? 0 : 1;
575 spin_unlock_bh(&td->tid_release_lock); 588 spin_unlock_bh(&td->tid_release_lock);
589
590 if (!td->nofail_skb)
591 td->nofail_skb =
592 alloc_skb(sizeof(struct cpl_tid_release),
593 GFP_KERNEL);
576} 594}
577 595
578/* use ctx as a next pointer in the tid release list */ 596/* use ctx as a next pointer in the tid release list */
@@ -585,7 +603,7 @@ void cxgb3_queue_tid_release(struct t3cdev *tdev, unsigned int tid)
585 p->ctx = (void *)td->tid_release_list; 603 p->ctx = (void *)td->tid_release_list;
586 p->client = NULL; 604 p->client = NULL;
587 td->tid_release_list = p; 605 td->tid_release_list = p;
588 if (!p->ctx) 606 if (!p->ctx || td->release_list_incomplete)
589 schedule_work(&td->tid_release_task); 607 schedule_work(&td->tid_release_task);
590 spin_unlock_bh(&td->tid_release_lock); 608 spin_unlock_bh(&td->tid_release_lock);
591} 609}
@@ -1274,6 +1292,9 @@ int cxgb3_offload_activate(struct adapter *adapter)
1274 if (list_empty(&adapter_list)) 1292 if (list_empty(&adapter_list))
1275 register_netevent_notifier(&nb); 1293 register_netevent_notifier(&nb);
1276 1294
1295 t->nofail_skb = alloc_skb(sizeof(struct cpl_tid_release), GFP_KERNEL);
1296 t->release_list_incomplete = 0;
1297
1277 add_adapter(adapter); 1298 add_adapter(adapter);
1278 return 0; 1299 return 0;
1279 1300
@@ -1298,6 +1319,8 @@ void cxgb3_offload_deactivate(struct adapter *adapter)
1298 T3C_DATA(tdev) = NULL; 1319 T3C_DATA(tdev) = NULL;
1299 t3_free_l2t(L2DATA(tdev)); 1320 t3_free_l2t(L2DATA(tdev));
1300 L2DATA(tdev) = NULL; 1321 L2DATA(tdev) = NULL;
1322 if (t->nofail_skb)
1323 kfree_skb(t->nofail_skb);
1301 kfree(t); 1324 kfree(t);
1302} 1325}
1303 1326