diff options
Diffstat (limited to 'drivers/infiniband/ulp')
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib.h | 5 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_main.c | 93 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 2 |
3 files changed, 48 insertions, 52 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index ca43901ed861..0af216d21f87 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h | |||
@@ -262,7 +262,10 @@ struct ipoib_ethtool_st { | |||
262 | u16 max_coalesced_frames; | 262 | u16 max_coalesced_frames; |
263 | }; | 263 | }; |
264 | 264 | ||
265 | struct ipoib_neigh_table; | ||
266 | |||
265 | struct ipoib_neigh_hash { | 267 | struct ipoib_neigh_hash { |
268 | struct ipoib_neigh_table *ntbl; | ||
266 | struct ipoib_neigh __rcu **buckets; | 269 | struct ipoib_neigh __rcu **buckets; |
267 | struct rcu_head rcu; | 270 | struct rcu_head rcu; |
268 | u32 mask; | 271 | u32 mask; |
@@ -271,9 +274,9 @@ struct ipoib_neigh_hash { | |||
271 | 274 | ||
272 | struct ipoib_neigh_table { | 275 | struct ipoib_neigh_table { |
273 | struct ipoib_neigh_hash __rcu *htbl; | 276 | struct ipoib_neigh_hash __rcu *htbl; |
274 | rwlock_t rwlock; | ||
275 | atomic_t entries; | 277 | atomic_t entries; |
276 | struct completion flushed; | 278 | struct completion flushed; |
279 | struct completion deleted; | ||
277 | }; | 280 | }; |
278 | 281 | ||
279 | /* | 282 | /* |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 3e2085a3ee47..1e19b5ae7c47 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
@@ -546,15 +546,15 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr, | |||
546 | struct ipoib_neigh *neigh; | 546 | struct ipoib_neigh *neigh; |
547 | unsigned long flags; | 547 | unsigned long flags; |
548 | 548 | ||
549 | spin_lock_irqsave(&priv->lock, flags); | ||
549 | neigh = ipoib_neigh_alloc(daddr, dev); | 550 | neigh = ipoib_neigh_alloc(daddr, dev); |
550 | if (!neigh) { | 551 | if (!neigh) { |
552 | spin_unlock_irqrestore(&priv->lock, flags); | ||
551 | ++dev->stats.tx_dropped; | 553 | ++dev->stats.tx_dropped; |
552 | dev_kfree_skb_any(skb); | 554 | dev_kfree_skb_any(skb); |
553 | return; | 555 | return; |
554 | } | 556 | } |
555 | 557 | ||
556 | spin_lock_irqsave(&priv->lock, flags); | ||
557 | |||
558 | path = __path_find(dev, daddr + 4); | 558 | path = __path_find(dev, daddr + 4); |
559 | if (!path) { | 559 | if (!path) { |
560 | path = path_rec_create(dev, daddr + 4); | 560 | path = path_rec_create(dev, daddr + 4); |
@@ -863,10 +863,10 @@ static void __ipoib_reap_neigh(struct ipoib_dev_priv *priv) | |||
863 | if (test_bit(IPOIB_STOP_NEIGH_GC, &priv->flags)) | 863 | if (test_bit(IPOIB_STOP_NEIGH_GC, &priv->flags)) |
864 | return; | 864 | return; |
865 | 865 | ||
866 | write_lock_bh(&ntbl->rwlock); | 866 | spin_lock_irqsave(&priv->lock, flags); |
867 | 867 | ||
868 | htbl = rcu_dereference_protected(ntbl->htbl, | 868 | htbl = rcu_dereference_protected(ntbl->htbl, |
869 | lockdep_is_held(&ntbl->rwlock)); | 869 | lockdep_is_held(&priv->lock)); |
870 | 870 | ||
871 | if (!htbl) | 871 | if (!htbl) |
872 | goto out_unlock; | 872 | goto out_unlock; |
@@ -883,16 +883,14 @@ static void __ipoib_reap_neigh(struct ipoib_dev_priv *priv) | |||
883 | struct ipoib_neigh __rcu **np = &htbl->buckets[i]; | 883 | struct ipoib_neigh __rcu **np = &htbl->buckets[i]; |
884 | 884 | ||
885 | while ((neigh = rcu_dereference_protected(*np, | 885 | while ((neigh = rcu_dereference_protected(*np, |
886 | lockdep_is_held(&ntbl->rwlock))) != NULL) { | 886 | lockdep_is_held(&priv->lock))) != NULL) { |
887 | /* was the neigh idle for two GC periods */ | 887 | /* was the neigh idle for two GC periods */ |
888 | if (time_after(neigh_obsolete, neigh->alive)) { | 888 | if (time_after(neigh_obsolete, neigh->alive)) { |
889 | rcu_assign_pointer(*np, | 889 | rcu_assign_pointer(*np, |
890 | rcu_dereference_protected(neigh->hnext, | 890 | rcu_dereference_protected(neigh->hnext, |
891 | lockdep_is_held(&ntbl->rwlock))); | 891 | lockdep_is_held(&priv->lock))); |
892 | /* remove from path/mc list */ | 892 | /* remove from path/mc list */ |
893 | spin_lock_irqsave(&priv->lock, flags); | ||
894 | list_del(&neigh->list); | 893 | list_del(&neigh->list); |
895 | spin_unlock_irqrestore(&priv->lock, flags); | ||
896 | call_rcu(&neigh->rcu, ipoib_neigh_reclaim); | 894 | call_rcu(&neigh->rcu, ipoib_neigh_reclaim); |
897 | } else { | 895 | } else { |
898 | np = &neigh->hnext; | 896 | np = &neigh->hnext; |
@@ -902,7 +900,7 @@ static void __ipoib_reap_neigh(struct ipoib_dev_priv *priv) | |||
902 | } | 900 | } |
903 | 901 | ||
904 | out_unlock: | 902 | out_unlock: |
905 | write_unlock_bh(&ntbl->rwlock); | 903 | spin_unlock_irqrestore(&priv->lock, flags); |
906 | } | 904 | } |
907 | 905 | ||
908 | static void ipoib_reap_neigh(struct work_struct *work) | 906 | static void ipoib_reap_neigh(struct work_struct *work) |
@@ -947,10 +945,8 @@ struct ipoib_neigh *ipoib_neigh_alloc(u8 *daddr, | |||
947 | struct ipoib_neigh *neigh; | 945 | struct ipoib_neigh *neigh; |
948 | u32 hash_val; | 946 | u32 hash_val; |
949 | 947 | ||
950 | write_lock_bh(&ntbl->rwlock); | ||
951 | |||
952 | htbl = rcu_dereference_protected(ntbl->htbl, | 948 | htbl = rcu_dereference_protected(ntbl->htbl, |
953 | lockdep_is_held(&ntbl->rwlock)); | 949 | lockdep_is_held(&priv->lock)); |
954 | if (!htbl) { | 950 | if (!htbl) { |
955 | neigh = NULL; | 951 | neigh = NULL; |
956 | goto out_unlock; | 952 | goto out_unlock; |
@@ -961,10 +957,10 @@ struct ipoib_neigh *ipoib_neigh_alloc(u8 *daddr, | |||
961 | */ | 957 | */ |
962 | hash_val = ipoib_addr_hash(htbl, daddr); | 958 | hash_val = ipoib_addr_hash(htbl, daddr); |
963 | for (neigh = rcu_dereference_protected(htbl->buckets[hash_val], | 959 | for (neigh = rcu_dereference_protected(htbl->buckets[hash_val], |
964 | lockdep_is_held(&ntbl->rwlock)); | 960 | lockdep_is_held(&priv->lock)); |
965 | neigh != NULL; | 961 | neigh != NULL; |
966 | neigh = rcu_dereference_protected(neigh->hnext, | 962 | neigh = rcu_dereference_protected(neigh->hnext, |
967 | lockdep_is_held(&ntbl->rwlock))) { | 963 | lockdep_is_held(&priv->lock))) { |
968 | if (memcmp(daddr, neigh->daddr, INFINIBAND_ALEN) == 0) { | 964 | if (memcmp(daddr, neigh->daddr, INFINIBAND_ALEN) == 0) { |
969 | /* found, take one ref on behalf of the caller */ | 965 | /* found, take one ref on behalf of the caller */ |
970 | if (!atomic_inc_not_zero(&neigh->refcnt)) { | 966 | if (!atomic_inc_not_zero(&neigh->refcnt)) { |
@@ -987,12 +983,11 @@ struct ipoib_neigh *ipoib_neigh_alloc(u8 *daddr, | |||
987 | /* put in hash */ | 983 | /* put in hash */ |
988 | rcu_assign_pointer(neigh->hnext, | 984 | rcu_assign_pointer(neigh->hnext, |
989 | rcu_dereference_protected(htbl->buckets[hash_val], | 985 | rcu_dereference_protected(htbl->buckets[hash_val], |
990 | lockdep_is_held(&ntbl->rwlock))); | 986 | lockdep_is_held(&priv->lock))); |
991 | rcu_assign_pointer(htbl->buckets[hash_val], neigh); | 987 | rcu_assign_pointer(htbl->buckets[hash_val], neigh); |
992 | atomic_inc(&ntbl->entries); | 988 | atomic_inc(&ntbl->entries); |
993 | 989 | ||
994 | out_unlock: | 990 | out_unlock: |
995 | write_unlock_bh(&ntbl->rwlock); | ||
996 | 991 | ||
997 | return neigh; | 992 | return neigh; |
998 | } | 993 | } |
@@ -1040,35 +1035,29 @@ void ipoib_neigh_free(struct ipoib_neigh *neigh) | |||
1040 | struct ipoib_neigh *n; | 1035 | struct ipoib_neigh *n; |
1041 | u32 hash_val; | 1036 | u32 hash_val; |
1042 | 1037 | ||
1043 | write_lock_bh(&ntbl->rwlock); | ||
1044 | |||
1045 | htbl = rcu_dereference_protected(ntbl->htbl, | 1038 | htbl = rcu_dereference_protected(ntbl->htbl, |
1046 | lockdep_is_held(&ntbl->rwlock)); | 1039 | lockdep_is_held(&priv->lock)); |
1047 | if (!htbl) | 1040 | if (!htbl) |
1048 | goto out_unlock; | 1041 | return; |
1049 | 1042 | ||
1050 | hash_val = ipoib_addr_hash(htbl, neigh->daddr); | 1043 | hash_val = ipoib_addr_hash(htbl, neigh->daddr); |
1051 | np = &htbl->buckets[hash_val]; | 1044 | np = &htbl->buckets[hash_val]; |
1052 | for (n = rcu_dereference_protected(*np, | 1045 | for (n = rcu_dereference_protected(*np, |
1053 | lockdep_is_held(&ntbl->rwlock)); | 1046 | lockdep_is_held(&priv->lock)); |
1054 | n != NULL; | 1047 | n != NULL; |
1055 | n = rcu_dereference_protected(*np, | 1048 | n = rcu_dereference_protected(*np, |
1056 | lockdep_is_held(&ntbl->rwlock))) { | 1049 | lockdep_is_held(&priv->lock))) { |
1057 | if (n == neigh) { | 1050 | if (n == neigh) { |
1058 | /* found */ | 1051 | /* found */ |
1059 | rcu_assign_pointer(*np, | 1052 | rcu_assign_pointer(*np, |
1060 | rcu_dereference_protected(neigh->hnext, | 1053 | rcu_dereference_protected(neigh->hnext, |
1061 | lockdep_is_held(&ntbl->rwlock))); | 1054 | lockdep_is_held(&priv->lock))); |
1062 | call_rcu(&neigh->rcu, ipoib_neigh_reclaim); | 1055 | call_rcu(&neigh->rcu, ipoib_neigh_reclaim); |
1063 | goto out_unlock; | 1056 | return; |
1064 | } else { | 1057 | } else { |
1065 | np = &n->hnext; | 1058 | np = &n->hnext; |
1066 | } | 1059 | } |
1067 | } | 1060 | } |
1068 | |||
1069 | out_unlock: | ||
1070 | write_unlock_bh(&ntbl->rwlock); | ||
1071 | |||
1072 | } | 1061 | } |
1073 | 1062 | ||
1074 | static int ipoib_neigh_hash_init(struct ipoib_dev_priv *priv) | 1063 | static int ipoib_neigh_hash_init(struct ipoib_dev_priv *priv) |
@@ -1080,7 +1069,6 @@ static int ipoib_neigh_hash_init(struct ipoib_dev_priv *priv) | |||
1080 | 1069 | ||
1081 | clear_bit(IPOIB_NEIGH_TBL_FLUSH, &priv->flags); | 1070 | clear_bit(IPOIB_NEIGH_TBL_FLUSH, &priv->flags); |
1082 | ntbl->htbl = NULL; | 1071 | ntbl->htbl = NULL; |
1083 | rwlock_init(&ntbl->rwlock); | ||
1084 | htbl = kzalloc(sizeof(*htbl), GFP_KERNEL); | 1072 | htbl = kzalloc(sizeof(*htbl), GFP_KERNEL); |
1085 | if (!htbl) | 1073 | if (!htbl) |
1086 | return -ENOMEM; | 1074 | return -ENOMEM; |
@@ -1095,6 +1083,7 @@ static int ipoib_neigh_hash_init(struct ipoib_dev_priv *priv) | |||
1095 | htbl->mask = (size - 1); | 1083 | htbl->mask = (size - 1); |
1096 | htbl->buckets = buckets; | 1084 | htbl->buckets = buckets; |
1097 | ntbl->htbl = htbl; | 1085 | ntbl->htbl = htbl; |
1086 | htbl->ntbl = ntbl; | ||
1098 | atomic_set(&ntbl->entries, 0); | 1087 | atomic_set(&ntbl->entries, 0); |
1099 | 1088 | ||
1100 | /* start garbage collection */ | 1089 | /* start garbage collection */ |
@@ -1111,9 +1100,11 @@ static void neigh_hash_free_rcu(struct rcu_head *head) | |||
1111 | struct ipoib_neigh_hash, | 1100 | struct ipoib_neigh_hash, |
1112 | rcu); | 1101 | rcu); |
1113 | struct ipoib_neigh __rcu **buckets = htbl->buckets; | 1102 | struct ipoib_neigh __rcu **buckets = htbl->buckets; |
1103 | struct ipoib_neigh_table *ntbl = htbl->ntbl; | ||
1114 | 1104 | ||
1115 | kfree(buckets); | 1105 | kfree(buckets); |
1116 | kfree(htbl); | 1106 | kfree(htbl); |
1107 | complete(&ntbl->deleted); | ||
1117 | } | 1108 | } |
1118 | 1109 | ||
1119 | void ipoib_del_neighs_by_gid(struct net_device *dev, u8 *gid) | 1110 | void ipoib_del_neighs_by_gid(struct net_device *dev, u8 *gid) |
@@ -1125,10 +1116,10 @@ void ipoib_del_neighs_by_gid(struct net_device *dev, u8 *gid) | |||
1125 | int i; | 1116 | int i; |
1126 | 1117 | ||
1127 | /* remove all neigh connected to a given path or mcast */ | 1118 | /* remove all neigh connected to a given path or mcast */ |
1128 | write_lock_bh(&ntbl->rwlock); | 1119 | spin_lock_irqsave(&priv->lock, flags); |
1129 | 1120 | ||
1130 | htbl = rcu_dereference_protected(ntbl->htbl, | 1121 | htbl = rcu_dereference_protected(ntbl->htbl, |
1131 | lockdep_is_held(&ntbl->rwlock)); | 1122 | lockdep_is_held(&priv->lock)); |
1132 | 1123 | ||
1133 | if (!htbl) | 1124 | if (!htbl) |
1134 | goto out_unlock; | 1125 | goto out_unlock; |
@@ -1138,16 +1129,14 @@ void ipoib_del_neighs_by_gid(struct net_device *dev, u8 *gid) | |||
1138 | struct ipoib_neigh __rcu **np = &htbl->buckets[i]; | 1129 | struct ipoib_neigh __rcu **np = &htbl->buckets[i]; |
1139 | 1130 | ||
1140 | while ((neigh = rcu_dereference_protected(*np, | 1131 | while ((neigh = rcu_dereference_protected(*np, |
1141 | lockdep_is_held(&ntbl->rwlock))) != NULL) { | 1132 | lockdep_is_held(&priv->lock))) != NULL) { |
1142 | /* delete neighs belong to this parent */ | 1133 | /* delete neighs belong to this parent */ |
1143 | if (!memcmp(gid, neigh->daddr + 4, sizeof (union ib_gid))) { | 1134 | if (!memcmp(gid, neigh->daddr + 4, sizeof (union ib_gid))) { |
1144 | rcu_assign_pointer(*np, | 1135 | rcu_assign_pointer(*np, |
1145 | rcu_dereference_protected(neigh->hnext, | 1136 | rcu_dereference_protected(neigh->hnext, |
1146 | lockdep_is_held(&ntbl->rwlock))); | 1137 | lockdep_is_held(&priv->lock))); |
1147 | /* remove from parent list */ | 1138 | /* remove from parent list */ |
1148 | spin_lock_irqsave(&priv->lock, flags); | ||
1149 | list_del(&neigh->list); | 1139 | list_del(&neigh->list); |
1150 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1151 | call_rcu(&neigh->rcu, ipoib_neigh_reclaim); | 1140 | call_rcu(&neigh->rcu, ipoib_neigh_reclaim); |
1152 | } else { | 1141 | } else { |
1153 | np = &neigh->hnext; | 1142 | np = &neigh->hnext; |
@@ -1156,7 +1145,7 @@ void ipoib_del_neighs_by_gid(struct net_device *dev, u8 *gid) | |||
1156 | } | 1145 | } |
1157 | } | 1146 | } |
1158 | out_unlock: | 1147 | out_unlock: |
1159 | write_unlock_bh(&ntbl->rwlock); | 1148 | spin_unlock_irqrestore(&priv->lock, flags); |
1160 | } | 1149 | } |
1161 | 1150 | ||
1162 | static void ipoib_flush_neighs(struct ipoib_dev_priv *priv) | 1151 | static void ipoib_flush_neighs(struct ipoib_dev_priv *priv) |
@@ -1164,37 +1153,44 @@ static void ipoib_flush_neighs(struct ipoib_dev_priv *priv) | |||
1164 | struct ipoib_neigh_table *ntbl = &priv->ntbl; | 1153 | struct ipoib_neigh_table *ntbl = &priv->ntbl; |
1165 | struct ipoib_neigh_hash *htbl; | 1154 | struct ipoib_neigh_hash *htbl; |
1166 | unsigned long flags; | 1155 | unsigned long flags; |
1167 | int i; | 1156 | int i, wait_flushed = 0; |
1168 | 1157 | ||
1169 | write_lock_bh(&ntbl->rwlock); | 1158 | init_completion(&priv->ntbl.flushed); |
1159 | |||
1160 | spin_lock_irqsave(&priv->lock, flags); | ||
1170 | 1161 | ||
1171 | htbl = rcu_dereference_protected(ntbl->htbl, | 1162 | htbl = rcu_dereference_protected(ntbl->htbl, |
1172 | lockdep_is_held(&ntbl->rwlock)); | 1163 | lockdep_is_held(&priv->lock)); |
1173 | if (!htbl) | 1164 | if (!htbl) |
1174 | goto out_unlock; | 1165 | goto out_unlock; |
1175 | 1166 | ||
1167 | wait_flushed = atomic_read(&priv->ntbl.entries); | ||
1168 | if (!wait_flushed) | ||
1169 | goto free_htbl; | ||
1170 | |||
1176 | for (i = 0; i < htbl->size; i++) { | 1171 | for (i = 0; i < htbl->size; i++) { |
1177 | struct ipoib_neigh *neigh; | 1172 | struct ipoib_neigh *neigh; |
1178 | struct ipoib_neigh __rcu **np = &htbl->buckets[i]; | 1173 | struct ipoib_neigh __rcu **np = &htbl->buckets[i]; |
1179 | 1174 | ||
1180 | while ((neigh = rcu_dereference_protected(*np, | 1175 | while ((neigh = rcu_dereference_protected(*np, |
1181 | lockdep_is_held(&ntbl->rwlock))) != NULL) { | 1176 | lockdep_is_held(&priv->lock))) != NULL) { |
1182 | rcu_assign_pointer(*np, | 1177 | rcu_assign_pointer(*np, |
1183 | rcu_dereference_protected(neigh->hnext, | 1178 | rcu_dereference_protected(neigh->hnext, |
1184 | lockdep_is_held(&ntbl->rwlock))); | 1179 | lockdep_is_held(&priv->lock))); |
1185 | /* remove from path/mc list */ | 1180 | /* remove from path/mc list */ |
1186 | spin_lock_irqsave(&priv->lock, flags); | ||
1187 | list_del(&neigh->list); | 1181 | list_del(&neigh->list); |
1188 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1189 | call_rcu(&neigh->rcu, ipoib_neigh_reclaim); | 1182 | call_rcu(&neigh->rcu, ipoib_neigh_reclaim); |
1190 | } | 1183 | } |
1191 | } | 1184 | } |
1192 | 1185 | ||
1186 | free_htbl: | ||
1193 | rcu_assign_pointer(ntbl->htbl, NULL); | 1187 | rcu_assign_pointer(ntbl->htbl, NULL); |
1194 | call_rcu(&htbl->rcu, neigh_hash_free_rcu); | 1188 | call_rcu(&htbl->rcu, neigh_hash_free_rcu); |
1195 | 1189 | ||
1196 | out_unlock: | 1190 | out_unlock: |
1197 | write_unlock_bh(&ntbl->rwlock); | 1191 | spin_unlock_irqrestore(&priv->lock, flags); |
1192 | if (wait_flushed) | ||
1193 | wait_for_completion(&priv->ntbl.flushed); | ||
1198 | } | 1194 | } |
1199 | 1195 | ||
1200 | static void ipoib_neigh_hash_uninit(struct net_device *dev) | 1196 | static void ipoib_neigh_hash_uninit(struct net_device *dev) |
@@ -1203,7 +1199,7 @@ static void ipoib_neigh_hash_uninit(struct net_device *dev) | |||
1203 | int stopped; | 1199 | int stopped; |
1204 | 1200 | ||
1205 | ipoib_dbg(priv, "ipoib_neigh_hash_uninit\n"); | 1201 | ipoib_dbg(priv, "ipoib_neigh_hash_uninit\n"); |
1206 | init_completion(&priv->ntbl.flushed); | 1202 | init_completion(&priv->ntbl.deleted); |
1207 | set_bit(IPOIB_NEIGH_TBL_FLUSH, &priv->flags); | 1203 | set_bit(IPOIB_NEIGH_TBL_FLUSH, &priv->flags); |
1208 | 1204 | ||
1209 | /* Stop GC if called at init fail need to cancel work */ | 1205 | /* Stop GC if called at init fail need to cancel work */ |
@@ -1211,10 +1207,9 @@ static void ipoib_neigh_hash_uninit(struct net_device *dev) | |||
1211 | if (!stopped) | 1207 | if (!stopped) |
1212 | cancel_delayed_work(&priv->neigh_reap_task); | 1208 | cancel_delayed_work(&priv->neigh_reap_task); |
1213 | 1209 | ||
1214 | if (atomic_read(&priv->ntbl.entries)) { | 1210 | ipoib_flush_neighs(priv); |
1215 | ipoib_flush_neighs(priv); | 1211 | |
1216 | wait_for_completion(&priv->ntbl.flushed); | 1212 | wait_for_completion(&priv->ntbl.deleted); |
1217 | } | ||
1218 | } | 1213 | } |
1219 | 1214 | ||
1220 | 1215 | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 13f4aa7593c8..75367249f447 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c | |||
@@ -707,9 +707,7 @@ out: | |||
707 | neigh = ipoib_neigh_get(dev, daddr); | 707 | neigh = ipoib_neigh_get(dev, daddr); |
708 | spin_lock_irqsave(&priv->lock, flags); | 708 | spin_lock_irqsave(&priv->lock, flags); |
709 | if (!neigh) { | 709 | if (!neigh) { |
710 | spin_unlock_irqrestore(&priv->lock, flags); | ||
711 | neigh = ipoib_neigh_alloc(daddr, dev); | 710 | neigh = ipoib_neigh_alloc(daddr, dev); |
712 | spin_lock_irqsave(&priv->lock, flags); | ||
713 | if (neigh) { | 711 | if (neigh) { |
714 | kref_get(&mcast->ah->ref); | 712 | kref_get(&mcast->ah->ref); |
715 | neigh->ah = mcast->ah; | 713 | neigh->ah = mcast->ah; |