aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFaisal Latif <faisal.latif@intel.com>2008-12-24 23:30:04 -0500
committerRoland Dreier <rolandd@cisco.com>2008-12-24 23:30:04 -0500
commite189062a8ca55b0a1843f0346c3fae1a47297c34 (patch)
treeebbe8fad6d9708764de679a03d3de1aacd99e9d4
parent6098d107499e1335f899bfcb558253fb7ee4f73f (diff)
RDMA/nes: Remove tx_free_list
There is no lock protecting tx_free_list thus causing a system crash when skb_dequeue() is called and the list is empty. Since it did not give any performance boost under heavy load, remove it to simplify the code. Replace get_free_pkt() with dev_alloc_skb() to allocate MAX_CM_BUFFER skb for connection establishment/teardown as well as MPA request/response. Signed-off-by: Faisal Latif <faisal.latif@intel.com> Signed-off-by: Chien Tung <chien.tin.tung@intel.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.c76
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.h5
2 files changed, 6 insertions, 75 deletions
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index aa373c5f8d84..cb48041bed69 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -94,7 +94,6 @@ static int mini_cm_set(struct nes_cm_core *, u32, u32);
94 94
95static void form_cm_frame(struct sk_buff *, struct nes_cm_node *, 95static void form_cm_frame(struct sk_buff *, struct nes_cm_node *,
96 void *, u32, void *, u32, u8); 96 void *, u32, void *, u32, u8);
97static struct sk_buff *get_free_pkt(struct nes_cm_node *cm_node);
98static int add_ref_cm_node(struct nes_cm_node *); 97static int add_ref_cm_node(struct nes_cm_node *);
99static int rem_ref_cm_node(struct nes_cm_core *, struct nes_cm_node *); 98static int rem_ref_cm_node(struct nes_cm_core *, struct nes_cm_node *);
100 99
@@ -355,7 +354,6 @@ static void print_core(struct nes_cm_core *core)
355 354
356 nes_debug(NES_DBG_CM, "State : %u \n", core->state); 355 nes_debug(NES_DBG_CM, "State : %u \n", core->state);
357 356
358 nes_debug(NES_DBG_CM, "Tx Free cnt : %u \n", skb_queue_len(&core->tx_free_list));
359 nes_debug(NES_DBG_CM, "Listen Nodes : %u \n", atomic_read(&core->listen_node_cnt)); 357 nes_debug(NES_DBG_CM, "Listen Nodes : %u \n", atomic_read(&core->listen_node_cnt));
360 nes_debug(NES_DBG_CM, "Active Nodes : %u \n", atomic_read(&core->node_cnt)); 358 nes_debug(NES_DBG_CM, "Active Nodes : %u \n", atomic_read(&core->node_cnt));
361 359
@@ -688,7 +686,7 @@ static int send_syn(struct nes_cm_node *cm_node, u32 sendack,
688 optionssize += 1; 686 optionssize += 1;
689 687
690 if (!skb) 688 if (!skb)
691 skb = get_free_pkt(cm_node); 689 skb = dev_alloc_skb(MAX_CM_BUFFER);
692 if (!skb) { 690 if (!skb) {
693 nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n"); 691 nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n");
694 return -1; 692 return -1;
@@ -713,7 +711,7 @@ static int send_reset(struct nes_cm_node *cm_node, struct sk_buff *skb)
713 int flags = SET_RST | SET_ACK; 711 int flags = SET_RST | SET_ACK;
714 712
715 if (!skb) 713 if (!skb)
716 skb = get_free_pkt(cm_node); 714 skb = dev_alloc_skb(MAX_CM_BUFFER);
717 if (!skb) { 715 if (!skb) {
718 nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n"); 716 nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n");
719 return -1; 717 return -1;
@@ -734,7 +732,7 @@ static int send_ack(struct nes_cm_node *cm_node, struct sk_buff *skb)
734 int ret; 732 int ret;
735 733
736 if (!skb) 734 if (!skb)
737 skb = get_free_pkt(cm_node); 735 skb = dev_alloc_skb(MAX_CM_BUFFER);
738 736
739 if (!skb) { 737 if (!skb) {
740 nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n"); 738 nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n");
@@ -757,7 +755,7 @@ static int send_fin(struct nes_cm_node *cm_node, struct sk_buff *skb)
757 755
758 /* if we didn't get a frame get one */ 756 /* if we didn't get a frame get one */
759 if (!skb) 757 if (!skb)
760 skb = get_free_pkt(cm_node); 758 skb = dev_alloc_skb(MAX_CM_BUFFER);
761 759
762 if (!skb) { 760 if (!skb) {
763 nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n"); 761 nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n");
@@ -772,59 +770,15 @@ static int send_fin(struct nes_cm_node *cm_node, struct sk_buff *skb)
772 770
773 771
774/** 772/**
775 * get_free_pkt
776 */
777static struct sk_buff *get_free_pkt(struct nes_cm_node *cm_node)
778{
779 struct sk_buff *skb, *new_skb;
780
781 /* check to see if we need to repopulate the free tx pkt queue */
782 if (skb_queue_len(&cm_node->cm_core->tx_free_list) < NES_CM_FREE_PKT_LO_WATERMARK) {
783 while (skb_queue_len(&cm_node->cm_core->tx_free_list) <
784 cm_node->cm_core->free_tx_pkt_max) {
785 /* replace the frame we took, we won't get it back */
786 new_skb = dev_alloc_skb(cm_node->cm_core->mtu);
787 BUG_ON(!new_skb);
788 /* add a replacement frame to the free tx list head */
789 skb_queue_head(&cm_node->cm_core->tx_free_list, new_skb);
790 }
791 }
792
793 skb = skb_dequeue(&cm_node->cm_core->tx_free_list);
794
795 return skb;
796}
797
798
799/**
800 * make_hashkey - generate hash key from node tuple
801 */
802static inline int make_hashkey(u16 loc_port, nes_addr_t loc_addr, u16 rem_port,
803 nes_addr_t rem_addr)
804{
805 u32 hashkey = 0;
806
807 hashkey = loc_addr + rem_addr + loc_port + rem_port;
808 hashkey = (hashkey % NES_CM_HASHTABLE_SIZE);
809
810 return hashkey;
811}
812
813
814/**
815 * find_node - find a cm node that matches the reference cm node 773 * find_node - find a cm node that matches the reference cm node
816 */ 774 */
817static struct nes_cm_node *find_node(struct nes_cm_core *cm_core, 775static struct nes_cm_node *find_node(struct nes_cm_core *cm_core,
818 u16 rem_port, nes_addr_t rem_addr, u16 loc_port, nes_addr_t loc_addr) 776 u16 rem_port, nes_addr_t rem_addr, u16 loc_port, nes_addr_t loc_addr)
819{ 777{
820 unsigned long flags; 778 unsigned long flags;
821 u32 hashkey;
822 struct list_head *hte; 779 struct list_head *hte;
823 struct nes_cm_node *cm_node; 780 struct nes_cm_node *cm_node;
824 781
825 /* make a hash index key for this packet */
826 hashkey = make_hashkey(loc_port, loc_addr, rem_port, rem_addr);
827
828 /* get a handle on the hte */ 782 /* get a handle on the hte */
829 hte = &cm_core->connected_nodes; 783 hte = &cm_core->connected_nodes;
830 784
@@ -892,7 +846,6 @@ static struct nes_cm_listener *find_listener(struct nes_cm_core *cm_core,
892static int add_hte_node(struct nes_cm_core *cm_core, struct nes_cm_node *cm_node) 846static int add_hte_node(struct nes_cm_core *cm_core, struct nes_cm_node *cm_node)
893{ 847{
894 unsigned long flags; 848 unsigned long flags;
895 u32 hashkey;
896 struct list_head *hte; 849 struct list_head *hte;
897 850
898 if (!cm_node || !cm_core) 851 if (!cm_node || !cm_core)
@@ -901,11 +854,6 @@ static int add_hte_node(struct nes_cm_core *cm_core, struct nes_cm_node *cm_node
901 nes_debug(NES_DBG_CM, "Adding Node %p to Active Connection HT\n", 854 nes_debug(NES_DBG_CM, "Adding Node %p to Active Connection HT\n",
902 cm_node); 855 cm_node);
903 856
904 /* first, make an index into our hash table */
905 hashkey = make_hashkey(cm_node->loc_port, cm_node->loc_addr,
906 cm_node->rem_port, cm_node->rem_addr);
907 cm_node->hashkey = hashkey;
908
909 spin_lock_irqsave(&cm_core->ht_lock, flags); 857 spin_lock_irqsave(&cm_core->ht_lock, flags);
910 858
911 /* get a handle on the hash table element (list head for this slot) */ 859 /* get a handle on the hash table element (list head for this slot) */
@@ -2198,10 +2146,7 @@ static int mini_cm_recv_pkt(struct nes_cm_core *cm_core,
2198 */ 2146 */
2199static struct nes_cm_core *nes_cm_alloc_core(void) 2147static struct nes_cm_core *nes_cm_alloc_core(void)
2200{ 2148{
2201 int i;
2202
2203 struct nes_cm_core *cm_core; 2149 struct nes_cm_core *cm_core;
2204 struct sk_buff *skb = NULL;
2205 2150
2206 /* setup the CM core */ 2151 /* setup the CM core */
2207 /* alloc top level core control structure */ 2152 /* alloc top level core control structure */
@@ -2219,19 +2164,6 @@ static struct nes_cm_core *nes_cm_alloc_core(void)
2219 2164
2220 atomic_set(&cm_core->events_posted, 0); 2165 atomic_set(&cm_core->events_posted, 0);
2221 2166
2222 /* init the packet lists */
2223 skb_queue_head_init(&cm_core->tx_free_list);
2224
2225 for (i = 0; i < NES_CM_DEFAULT_FRAME_CNT; i++) {
2226 skb = dev_alloc_skb(cm_core->mtu);
2227 if (!skb) {
2228 kfree(cm_core);
2229 return NULL;
2230 }
2231 /* add 'raw' skb to free frame list */
2232 skb_queue_head(&cm_core->tx_free_list, skb);
2233 }
2234
2235 cm_core->api = &nes_cm_api; 2167 cm_core->api = &nes_cm_api;
2236 2168
2237 spin_lock_init(&cm_core->ht_lock); 2169 spin_lock_init(&cm_core->ht_lock);
diff --git a/drivers/infiniband/hw/nes/nes_cm.h b/drivers/infiniband/hw/nes/nes_cm.h
index 3a20a7883976..fafa35042ebd 100644
--- a/drivers/infiniband/hw/nes/nes_cm.h
+++ b/drivers/infiniband/hw/nes/nes_cm.h
@@ -165,6 +165,8 @@ struct nes_timer_entry {
165 165
166#define NES_CM_DEF_SEQ2 0x18ed5740 166#define NES_CM_DEF_SEQ2 0x18ed5740
167#define NES_CM_DEF_LOCAL_ID2 0xb807 167#define NES_CM_DEF_LOCAL_ID2 0xb807
168#define MAX_CM_BUFFER 512
169
168 170
169typedef u32 nes_addr_t; 171typedef u32 nes_addr_t;
170 172
@@ -258,8 +260,6 @@ struct nes_cm_listener {
258 260
259/* per connection node and node state information */ 261/* per connection node and node state information */
260struct nes_cm_node { 262struct nes_cm_node {
261 u32 hashkey;
262
263 nes_addr_t loc_addr, rem_addr; 263 nes_addr_t loc_addr, rem_addr;
264 u16 loc_port, rem_port; 264 u16 loc_port, rem_port;
265 265
@@ -357,7 +357,6 @@ struct nes_cm_core {
357 u32 mtu; 357 u32 mtu;
358 u32 free_tx_pkt_max; 358 u32 free_tx_pkt_max;
359 u32 rx_pkt_posted; 359 u32 rx_pkt_posted;
360 struct sk_buff_head tx_free_list;
361 atomic_t ht_node_cnt; 360 atomic_t ht_node_cnt;
362 struct list_head connected_nodes; 361 struct list_head connected_nodes;
363 /* struct list_head hashtable[NES_CM_HASHTABLE_SIZE]; */ 362 /* struct list_head hashtable[NES_CM_HASHTABLE_SIZE]; */