Skip to content

Commit 0cda611

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma
Pull base rdma updates from Doug Ledford: "Round one of 4.8 code: while this is mostly normal, there is a new driver in here (the driver was hosted outside the kernel for several years and is actually a fairly mature and well coded driver). It amounts to 13,000 of the 16,000 lines of added code in here. Summary: - Updates/fixes for iw_cxgb4 driver - Updates/fixes for mlx5 driver - Add flow steering and RSS API - Add hardware stats to mlx4 and mlx5 drivers - Add firmware version API for RDMA driver use - Add the rxe driver (this is a software RoCE driver that makes any Ethernet device a RoCE device) - Fixes for i40iw driver - Support for send only multicast joins in the cma layer - Other minor fixes" * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma: (72 commits) Soft RoCE driver IB/core: Support for CMA multicast join flags IB/sa: Add cached attribute containing SM information to SA port IB/uverbs: Fix race between uverbs_close and remove_one IB/mthca: Clean up error unwind flow in mthca_reset() IB/mthca: NULL arg to pci_dev_put is OK IB/hfi1: NULL arg to sc_return_credits is OK IB/mlx4: Add diagnostic hardware counters net/mlx4: Query performance and diagnostics counters net/mlx4: Add diagnostic counters capability bit Use smaller 512 byte messages for portmapper messages IB/ipoib: Report SG feature regardless of HW UD CSUM capability IB/mlx4: Don't use GFP_ATOMIC for CQ resize struct IB/hfi1: Disable by default IB/rdmavt: Disable by default IB/mlx5: Fix port counter ID association to QP offset IB/mlx5: Fix iteration overrun in GSI qps i40iw: Add NULL check for puda buffer i40iw: Change dup_ack_thresh to u8 i40iw: Remove unnecessary check for moving CQ head ...
2 parents fdf1f7f + 7f1d25b commit 0cda611

107 files changed

Lines changed: 16539 additions & 663 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

MAINTAINERS

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7647,6 +7647,15 @@ W: http://www.mellanox.com
76477647
Q: http://patchwork.ozlabs.org/project/netdev/list/
76487648
F: drivers/net/ethernet/mellanox/mlxsw/
76497649

7650+
SOFT-ROCE DRIVER (rxe)
7651+
M: Moni Shoua <monis@mellanox.com>
7652+
L: linux-rdma@vger.kernel.org
7653+
S: Supported
7654+
W: https://github.com/SoftRoCE/rxe-dev/wiki/rxe-dev:-Home
7655+
Q: http://patchwork.kernel.org/project/linux-rdma/list/
7656+
F: drivers/infiniband/hw/rxe/
7657+
F: include/uapi/rdma/rdma_user_rxe.h
7658+
76507659
MEMBARRIER SUPPORT
76517660
M: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
76527661
M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>

drivers/infiniband/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ source "drivers/infiniband/ulp/iser/Kconfig"
8484
source "drivers/infiniband/ulp/isert/Kconfig"
8585

8686
source "drivers/infiniband/sw/rdmavt/Kconfig"
87+
source "drivers/infiniband/sw/rxe/Kconfig"
8788

8889
source "drivers/infiniband/hw/hfi1/Kconfig"
8990

drivers/infiniband/core/cma.c

Lines changed: 92 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ MODULE_DESCRIPTION("Generic RDMA CM Agent");
6868
MODULE_LICENSE("Dual BSD/GPL");
6969

7070
#define CMA_CM_RESPONSE_TIMEOUT 20
71+
#define CMA_QUERY_CLASSPORT_INFO_TIMEOUT 3000
7172
#define CMA_MAX_CM_RETRIES 15
7273
#define CMA_CM_MRA_SETTING (IB_CM_MRA_FLAG_DELAY | 24)
7374
#define CMA_IBOE_PACKET_LIFETIME 18
@@ -162,6 +163,14 @@ struct rdma_bind_list {
162163
unsigned short port;
163164
};
164165

166+
struct class_port_info_context {
167+
struct ib_class_port_info *class_port_info;
168+
struct ib_device *device;
169+
struct completion done;
170+
struct ib_sa_query *sa_query;
171+
u8 port_num;
172+
};
173+
165174
static int cma_ps_alloc(struct net *net, enum rdma_port_space ps,
166175
struct rdma_bind_list *bind_list, int snum)
167176
{
@@ -306,6 +315,7 @@ struct cma_multicast {
306315
struct sockaddr_storage addr;
307316
struct kref mcref;
308317
bool igmp_joined;
318+
u8 join_state;
309319
};
310320

311321
struct cma_work {
@@ -3752,10 +3762,63 @@ static void cma_set_mgid(struct rdma_id_private *id_priv,
37523762
}
37533763
}
37543764

3765+
static void cma_query_sa_classport_info_cb(int status,
3766+
struct ib_class_port_info *rec,
3767+
void *context)
3768+
{
3769+
struct class_port_info_context *cb_ctx = context;
3770+
3771+
WARN_ON(!context);
3772+
3773+
if (status || !rec) {
3774+
pr_debug("RDMA CM: %s port %u failed query ClassPortInfo status: %d\n",
3775+
cb_ctx->device->name, cb_ctx->port_num, status);
3776+
goto out;
3777+
}
3778+
3779+
memcpy(cb_ctx->class_port_info, rec, sizeof(struct ib_class_port_info));
3780+
3781+
out:
3782+
complete(&cb_ctx->done);
3783+
}
3784+
3785+
static int cma_query_sa_classport_info(struct ib_device *device, u8 port_num,
3786+
struct ib_class_port_info *class_port_info)
3787+
{
3788+
struct class_port_info_context *cb_ctx;
3789+
int ret;
3790+
3791+
cb_ctx = kmalloc(sizeof(*cb_ctx), GFP_KERNEL);
3792+
if (!cb_ctx)
3793+
return -ENOMEM;
3794+
3795+
cb_ctx->device = device;
3796+
cb_ctx->class_port_info = class_port_info;
3797+
cb_ctx->port_num = port_num;
3798+
init_completion(&cb_ctx->done);
3799+
3800+
ret = ib_sa_classport_info_rec_query(&sa_client, device, port_num,
3801+
CMA_QUERY_CLASSPORT_INFO_TIMEOUT,
3802+
GFP_KERNEL, cma_query_sa_classport_info_cb,
3803+
cb_ctx, &cb_ctx->sa_query);
3804+
if (ret < 0) {
3805+
pr_err("RDMA CM: %s port %u failed to send ClassPortInfo query, ret: %d\n",
3806+
device->name, port_num, ret);
3807+
goto out;
3808+
}
3809+
3810+
wait_for_completion(&cb_ctx->done);
3811+
3812+
out:
3813+
kfree(cb_ctx);
3814+
return ret;
3815+
}
3816+
37553817
static int cma_join_ib_multicast(struct rdma_id_private *id_priv,
37563818
struct cma_multicast *mc)
37573819
{
37583820
struct ib_sa_mcmember_rec rec;
3821+
struct ib_class_port_info class_port_info;
37593822
struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr;
37603823
ib_sa_comp_mask comp_mask;
37613824
int ret;
@@ -3774,7 +3837,24 @@ static int cma_join_ib_multicast(struct rdma_id_private *id_priv,
37743837
rec.qkey = cpu_to_be32(id_priv->qkey);
37753838
rdma_addr_get_sgid(dev_addr, &rec.port_gid);
37763839
rec.pkey = cpu_to_be16(ib_addr_get_pkey(dev_addr));
3777-
rec.join_state = 1;
3840+
rec.join_state = mc->join_state;
3841+
3842+
if (rec.join_state == BIT(SENDONLY_FULLMEMBER_JOIN)) {
3843+
ret = cma_query_sa_classport_info(id_priv->id.device,
3844+
id_priv->id.port_num,
3845+
&class_port_info);
3846+
3847+
if (ret)
3848+
return ret;
3849+
3850+
if (!(ib_get_cpi_capmask2(&class_port_info) &
3851+
IB_SA_CAP_MASK2_SENDONLY_FULL_MEM_SUPPORT)) {
3852+
pr_warn("RDMA CM: %s port %u Unable to multicast join\n"
3853+
"RDMA CM: SM doesn't support Send Only Full Member option\n",
3854+
id_priv->id.device->name, id_priv->id.port_num);
3855+
return -EOPNOTSUPP;
3856+
}
3857+
}
37783858

37793859
comp_mask = IB_SA_MCMEMBER_REC_MGID | IB_SA_MCMEMBER_REC_PORT_GID |
37803860
IB_SA_MCMEMBER_REC_PKEY | IB_SA_MCMEMBER_REC_JOIN_STATE |
@@ -3843,6 +3923,9 @@ static int cma_iboe_join_multicast(struct rdma_id_private *id_priv,
38433923
struct sockaddr *addr = (struct sockaddr *)&mc->addr;
38443924
struct net_device *ndev = NULL;
38453925
enum ib_gid_type gid_type;
3926+
bool send_only;
3927+
3928+
send_only = mc->join_state == BIT(SENDONLY_FULLMEMBER_JOIN);
38463929

38473930
if (cma_zero_addr((struct sockaddr *)&mc->addr))
38483931
return -EINVAL;
@@ -3878,10 +3961,12 @@ static int cma_iboe_join_multicast(struct rdma_id_private *id_priv,
38783961
if (addr->sa_family == AF_INET) {
38793962
if (gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP) {
38803963
mc->multicast.ib->rec.hop_limit = IPV6_DEFAULT_HOPLIMIT;
3881-
err = cma_igmp_send(ndev, &mc->multicast.ib->rec.mgid,
3882-
true);
3883-
if (!err)
3884-
mc->igmp_joined = true;
3964+
if (!send_only) {
3965+
err = cma_igmp_send(ndev, &mc->multicast.ib->rec.mgid,
3966+
true);
3967+
if (!err)
3968+
mc->igmp_joined = true;
3969+
}
38853970
}
38863971
} else {
38873972
if (gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP)
@@ -3911,7 +3996,7 @@ static int cma_iboe_join_multicast(struct rdma_id_private *id_priv,
39113996
}
39123997

39133998
int rdma_join_multicast(struct rdma_cm_id *id, struct sockaddr *addr,
3914-
void *context)
3999+
u8 join_state, void *context)
39154000
{
39164001
struct rdma_id_private *id_priv;
39174002
struct cma_multicast *mc;
@@ -3930,6 +4015,7 @@ int rdma_join_multicast(struct rdma_cm_id *id, struct sockaddr *addr,
39304015
mc->context = context;
39314016
mc->id_priv = id_priv;
39324017
mc->igmp_joined = false;
4018+
mc->join_state = join_state;
39334019
spin_lock(&id_priv->lock);
39344020
list_add(&mc->list, &id_priv->mc_list);
39354021
spin_unlock(&id_priv->lock);

drivers/infiniband/core/device.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,15 @@ static int read_port_immutable(struct ib_device *device)
311311
return 0;
312312
}
313313

314+
void ib_get_device_fw_str(struct ib_device *dev, char *str, size_t str_len)
315+
{
316+
if (dev->get_dev_fw_str)
317+
dev->get_dev_fw_str(dev, str, str_len);
318+
else
319+
str[0] = '\0';
320+
}
321+
EXPORT_SYMBOL(ib_get_device_fw_str);
322+
314323
/**
315324
* ib_register_device - Register an IB device with IB core
316325
* @device:Device to register

drivers/infiniband/core/iwcm.c

Lines changed: 17 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -183,15 +183,14 @@ static void free_cm_id(struct iwcm_id_private *cm_id_priv)
183183

184184
/*
185185
* Release a reference on cm_id. If the last reference is being
186-
* released, enable the waiting thread (in iw_destroy_cm_id) to
187-
* get woken up, and return 1 if a thread is already waiting.
186+
* released, free the cm_id and return 1.
188187
*/
189188
static int iwcm_deref_id(struct iwcm_id_private *cm_id_priv)
190189
{
191190
BUG_ON(atomic_read(&cm_id_priv->refcount)==0);
192191
if (atomic_dec_and_test(&cm_id_priv->refcount)) {
193192
BUG_ON(!list_empty(&cm_id_priv->work_list));
194-
complete(&cm_id_priv->destroy_comp);
193+
free_cm_id(cm_id_priv);
195194
return 1;
196195
}
197196

@@ -208,19 +207,10 @@ static void add_ref(struct iw_cm_id *cm_id)
208207
static void rem_ref(struct iw_cm_id *cm_id)
209208
{
210209
struct iwcm_id_private *cm_id_priv;
211-
int cb_destroy;
212210

213211
cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
214212

215-
/*
216-
* Test bit before deref in case the cm_id gets freed on another
217-
* thread.
218-
*/
219-
cb_destroy = test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags);
220-
if (iwcm_deref_id(cm_id_priv) && cb_destroy) {
221-
BUG_ON(!list_empty(&cm_id_priv->work_list));
222-
free_cm_id(cm_id_priv);
223-
}
213+
(void)iwcm_deref_id(cm_id_priv);
224214
}
225215

226216
static int cm_event_handler(struct iw_cm_id *cm_id, struct iw_cm_event *event);
@@ -370,6 +360,12 @@ static void destroy_cm_id(struct iw_cm_id *cm_id)
370360
wait_event(cm_id_priv->connect_wait,
371361
!test_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags));
372362

363+
/*
364+
* Since we're deleting the cm_id, drop any events that
365+
* might arrive before the last dereference.
366+
*/
367+
set_bit(IWCM_F_DROP_EVENTS, &cm_id_priv->flags);
368+
373369
spin_lock_irqsave(&cm_id_priv->lock, flags);
374370
switch (cm_id_priv->state) {
375371
case IW_CM_STATE_LISTEN:
@@ -433,13 +429,7 @@ void iw_destroy_cm_id(struct iw_cm_id *cm_id)
433429
struct iwcm_id_private *cm_id_priv;
434430

435431
cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
436-
BUG_ON(test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags));
437-
438432
destroy_cm_id(cm_id);
439-
440-
wait_for_completion(&cm_id_priv->destroy_comp);
441-
442-
free_cm_id(cm_id_priv);
443433
}
444434
EXPORT_SYMBOL(iw_destroy_cm_id);
445435

@@ -809,10 +799,7 @@ static void cm_conn_req_handler(struct iwcm_id_private *listen_id_priv,
809799
ret = cm_id->cm_handler(cm_id, iw_event);
810800
if (ret) {
811801
iw_cm_reject(cm_id, NULL, 0);
812-
set_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags);
813-
destroy_cm_id(cm_id);
814-
if (atomic_read(&cm_id_priv->refcount)==0)
815-
free_cm_id(cm_id_priv);
802+
iw_destroy_cm_id(cm_id);
816803
}
817804

818805
out:
@@ -1000,7 +987,6 @@ static void cm_work_handler(struct work_struct *_work)
1000987
unsigned long flags;
1001988
int empty;
1002989
int ret = 0;
1003-
int destroy_id;
1004990

1005991
spin_lock_irqsave(&cm_id_priv->lock, flags);
1006992
empty = list_empty(&cm_id_priv->work_list);
@@ -1013,20 +999,14 @@ static void cm_work_handler(struct work_struct *_work)
1013999
put_work(work);
10141000
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
10151001

1016-
ret = process_event(cm_id_priv, &levent);
1017-
if (ret) {
1018-
set_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags);
1019-
destroy_cm_id(&cm_id_priv->id);
1020-
}
1021-
BUG_ON(atomic_read(&cm_id_priv->refcount)==0);
1022-
destroy_id = test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags);
1023-
if (iwcm_deref_id(cm_id_priv)) {
1024-
if (destroy_id) {
1025-
BUG_ON(!list_empty(&cm_id_priv->work_list));
1026-
free_cm_id(cm_id_priv);
1027-
}
1002+
if (!test_bit(IWCM_F_DROP_EVENTS, &cm_id_priv->flags)) {
1003+
ret = process_event(cm_id_priv, &levent);
1004+
if (ret)
1005+
destroy_cm_id(&cm_id_priv->id);
1006+
} else
1007+
pr_debug("dropping event %d\n", levent.event);
1008+
if (iwcm_deref_id(cm_id_priv))
10281009
return;
1029-
}
10301010
if (empty)
10311011
return;
10321012
spin_lock_irqsave(&cm_id_priv->lock, flags);

drivers/infiniband/core/iwcm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ struct iwcm_id_private {
5656
struct list_head work_free_list;
5757
};
5858

59-
#define IWCM_F_CALLBACK_DESTROY 1
59+
#define IWCM_F_DROP_EVENTS 1
6060
#define IWCM_F_CONNECT_WAIT 2
6161

6262
#endif /* IWCM_H */

drivers/infiniband/core/iwpm_util.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#define IWPM_MAPINFO_HASH_MASK (IWPM_MAPINFO_HASH_SIZE - 1)
3838
#define IWPM_REMINFO_HASH_SIZE 64
3939
#define IWPM_REMINFO_HASH_MASK (IWPM_REMINFO_HASH_SIZE - 1)
40+
#define IWPM_MSG_SIZE 512
4041

4142
static LIST_HEAD(iwpm_nlmsg_req_list);
4243
static DEFINE_SPINLOCK(iwpm_nlmsg_req_lock);
@@ -452,7 +453,7 @@ struct sk_buff *iwpm_create_nlmsg(u32 nl_op, struct nlmsghdr **nlh,
452453
{
453454
struct sk_buff *skb = NULL;
454455

455-
skb = dev_alloc_skb(NLMSG_GOODSIZE);
456+
skb = dev_alloc_skb(IWPM_MSG_SIZE);
456457
if (!skb) {
457458
pr_err("%s Unable to allocate skb\n", __func__);
458459
goto create_nlmsg_exit;

drivers/infiniband/core/multicast.c

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -93,18 +93,6 @@ enum {
9393

9494
struct mcast_member;
9595

96-
/*
97-
* There are 4 types of join states:
98-
* FullMember, NonMember, SendOnlyNonMember, SendOnlyFullMember.
99-
*/
100-
enum {
101-
FULLMEMBER_JOIN,
102-
NONMEMBER_JOIN,
103-
SENDONLY_NONMEBER_JOIN,
104-
SENDONLY_FULLMEMBER_JOIN,
105-
NUM_JOIN_MEMBERSHIP_TYPES,
106-
};
107-
10896
struct mcast_group {
10997
struct ib_sa_mcmember_rec rec;
11098
struct rb_node node;

drivers/infiniband/core/netlink.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,10 @@ static void ibnl_rcv(struct sk_buff *skb)
229229
int ibnl_unicast(struct sk_buff *skb, struct nlmsghdr *nlh,
230230
__u32 pid)
231231
{
232-
return nlmsg_unicast(nls, skb, pid);
232+
int err;
233+
234+
err = netlink_unicast(nls, skb, pid, 0);
235+
return (err < 0) ? err : 0;
233236
}
234237
EXPORT_SYMBOL(ibnl_unicast);
235238

@@ -252,6 +255,7 @@ int __init ibnl_init(void)
252255
return -ENOMEM;
253256
}
254257

258+
nls->sk_sndtimeo = 10 * HZ;
255259
return 0;
256260
}
257261

0 commit comments

Comments
 (0)