diff options
author | Faisal Latif <faisal.latif@intel.com> | 2008-12-24 23:30:04 -0500 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2008-12-24 23:30:04 -0500 |
commit | e189062a8ca55b0a1843f0346c3fae1a47297c34 (patch) | |
tree | ebbe8fad6d9708764de679a03d3de1aacd99e9d4 | |
parent | 6098d107499e1335f899bfcb558253fb7ee4f73f (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.c | 76 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_cm.h | 5 |
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 | ||
95 | static void form_cm_frame(struct sk_buff *, struct nes_cm_node *, | 95 | static void form_cm_frame(struct sk_buff *, struct nes_cm_node *, |
96 | void *, u32, void *, u32, u8); | 96 | void *, u32, void *, u32, u8); |
97 | static struct sk_buff *get_free_pkt(struct nes_cm_node *cm_node); | ||
98 | static int add_ref_cm_node(struct nes_cm_node *); | 97 | static int add_ref_cm_node(struct nes_cm_node *); |
99 | static int rem_ref_cm_node(struct nes_cm_core *, struct nes_cm_node *); | 98 | static 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 | */ | ||
777 | static 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 | */ | ||
802 | static 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 | */ |
817 | static struct nes_cm_node *find_node(struct nes_cm_core *cm_core, | 775 | static 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, | |||
892 | static int add_hte_node(struct nes_cm_core *cm_core, struct nes_cm_node *cm_node) | 846 | static 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 | */ |
2199 | static struct nes_cm_core *nes_cm_alloc_core(void) | 2147 | static 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 | ||
169 | typedef u32 nes_addr_t; | 171 | typedef 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 */ |
260 | struct nes_cm_node { | 262 | struct 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]; */ |