Skip to content

Commit 119a8e7

Browse files
Kamal Heibdledford
authored andcommitted
IB/rdmavt: Add AH to rdmavt
Original patch is from Kamal Heib <[email protected]>. It has been split into three separate patches. This one for rdmavt, a follow on for qib, and one for hfi1. Create datastructure for address handle and implement the create/destroy/modify/query of address handle for rdmavt. Reviewed-by: Ira Weiny <[email protected]> Signed-off-by: Kamal Heib <[email protected]> Signed-off-by: Dennis Dalessandro <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent f2f3421 commit 119a8e7

File tree

3 files changed

+115
-5
lines changed

3 files changed

+115
-5
lines changed

drivers/infiniband/sw/rdmavt/ah.c

Lines changed: 94 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,49 @@
4545
*
4646
*/
4747

48+
#include <linux/slab.h>
4849
#include "ah.h"
50+
#include "vt.h" /* for prints */
51+
52+
/**
53+
* rvt_check_ah - validate the attributes of AH
54+
* @ibdev: the ib device
55+
* @ah_attr: the attributes of the AH
56+
*/
57+
int rvt_check_ah(struct ib_device *ibdev,
58+
struct ib_ah_attr *ah_attr)
59+
{
60+
int err;
61+
struct ib_port_attr port_attr;
62+
struct rvt_dev_info *rdi = ib_to_rvt(ibdev);
63+
enum rdma_link_layer link = rdma_port_get_link_layer(ibdev,
64+
ah_attr->port_num);
65+
66+
err = ib_query_port(ibdev, ah_attr->port_num, &port_attr);
67+
if (err)
68+
return -EINVAL;
69+
if (ah_attr->port_num < 1 ||
70+
ah_attr->port_num > ibdev->phys_port_cnt)
71+
return -EINVAL;
72+
if (ah_attr->static_rate != IB_RATE_PORT_CURRENT &&
73+
ib_rate_to_mbps(ah_attr->static_rate) < 0)
74+
return -EINVAL;
75+
if ((ah_attr->ah_flags & IB_AH_GRH) &&
76+
ah_attr->grh.sgid_index >= port_attr.gid_tbl_len)
77+
return -EINVAL;
78+
if (link != IB_LINK_LAYER_ETHERNET) {
79+
if (ah_attr->dlid == 0)
80+
return -EINVAL;
81+
if (ah_attr->dlid >= RVT_MULTICAST_LID_BASE &&
82+
ah_attr->dlid != RVT_PERMISSIVE_LID &&
83+
!(ah_attr->ah_flags & IB_AH_GRH))
84+
return -EINVAL;
85+
}
86+
if (rdi->driver_f.check_ah(ibdev, ah_attr))
87+
return -EINVAL;
88+
return 0;
89+
}
90+
EXPORT_SYMBOL(rvt_check_ah);
4991

5092
/**
5193
* rvt_create_ah - create an address handle
@@ -57,20 +99,68 @@
5799
struct ib_ah *rvt_create_ah(struct ib_pd *pd,
58100
struct ib_ah_attr *ah_attr)
59101
{
60-
return ERR_PTR(-EOPNOTSUPP);
102+
struct rvt_ah *ah;
103+
struct rvt_dev_info *dev = ib_to_rvt(pd->device);
104+
unsigned long flags;
105+
106+
if (rvt_check_ah(pd->device, ah_attr))
107+
return ERR_PTR(-EINVAL);
108+
109+
ah = kmalloc(sizeof(*ah), GFP_ATOMIC);
110+
if (!ah)
111+
return ERR_PTR(-ENOMEM);
112+
113+
spin_lock_irqsave(&dev->n_ahs_lock, flags);
114+
if (dev->n_ahs_allocated == dev->dparms.props.max_ah) {
115+
spin_unlock(&dev->n_ahs_lock);
116+
kfree(ah);
117+
return ERR_PTR(-ENOMEM);
118+
}
119+
120+
dev->n_ahs_allocated++;
121+
spin_unlock_irqrestore(&dev->n_ahs_lock, flags);
122+
123+
ah->attr = *ah_attr;
124+
atomic_set(&ah->refcount, 0);
125+
126+
return &ah->ibah;
61127
}
62128

63129
int rvt_destroy_ah(struct ib_ah *ibah)
64130
{
65-
return -EOPNOTSUPP;
131+
struct rvt_dev_info *dev = ib_to_rvt(ibah->device);
132+
struct rvt_ah *ah = ibah_to_rvtah(ibah);
133+
unsigned long flags;
134+
135+
if (atomic_read(&ah->refcount) != 0)
136+
return -EBUSY;
137+
138+
spin_lock_irqsave(&dev->n_ahs_lock, flags);
139+
dev->n_ahs_allocated--;
140+
spin_unlock_irqrestore(&dev->n_ahs_lock, flags);
141+
142+
kfree(ah);
143+
144+
return 0;
66145
}
67146

68147
int rvt_modify_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr)
69148
{
70-
return -EOPNOTSUPP;
149+
struct rvt_ah *ah = ibah_to_rvtah(ibah);
150+
151+
if (rvt_check_ah(ibah->device, ah_attr))
152+
return -EINVAL;
153+
154+
ah->attr = *ah_attr;
155+
156+
return 0;
71157
}
72158

73159
int rvt_query_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr)
74160
{
75-
return -EOPNOTSUPP;
161+
struct rvt_ah *ah = ibah_to_rvtah(ibah);
162+
163+
*ah_attr = ah->attr;
164+
165+
return 0;
76166
}

drivers/infiniband/sw/rdmavt/vt.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,8 @@ int rvt_register_device(struct rvt_dev_info *rdi)
221221

222222
if ((!rdi->driver_f.port_callback) ||
223223
(!rdi->driver_f.get_card_name) ||
224-
(!rdi->driver_f.get_pci_dev)) {
224+
(!rdi->driver_f.get_pci_dev) ||
225+
(!rdi->driver_f.check_ah)) {
225226
return -EINVAL;
226227
}
227228

@@ -252,6 +253,8 @@ int rvt_register_device(struct rvt_dev_info *rdi)
252253
CHECK_DRIVER_OVERRIDE(rdi, destroy_ah);
253254
CHECK_DRIVER_OVERRIDE(rdi, modify_ah);
254255
CHECK_DRIVER_OVERRIDE(rdi, query_ah);
256+
spin_lock_init(&rdi->n_ahs_lock);
257+
rdi->n_ahs_allocated = 0;
255258

256259
/* Shared Receive Queue */
257260
CHECK_DRIVER_OVERRIDE(rdi, create_srq);

include/rdma/rdma_vt.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,7 @@ struct rvt_driver_provided {
411411
int (*port_callback)(struct ib_device *, u8, struct kobject *);
412412
const char * (*get_card_name)(struct rvt_dev_info *rdi);
413413
struct pci_dev * (*get_pci_dev)(struct rvt_dev_info *rdi);
414+
int (*check_ah)(struct ib_device *, struct ib_ah_attr *);
414415
};
415416

416417
/* Protection domain */
@@ -419,6 +420,13 @@ struct rvt_pd {
419420
int user; /* non-zero if created from user space */
420421
};
421422

423+
/* Address handle */
424+
struct rvt_ah {
425+
struct ib_ah ibah;
426+
struct ib_ah_attr attr;
427+
atomic_t refcount;
428+
};
429+
422430
struct rvt_dev_info {
423431
struct ib_device ibdev; /* Keep this first. Nothing above here */
424432

@@ -445,6 +453,9 @@ struct rvt_dev_info {
445453
int n_pds_allocated;
446454
spinlock_t n_pds_lock; /* Protect pd allocated count */
447455

456+
int n_ahs_allocated;
457+
spinlock_t n_ahs_lock; /* Protect ah allocated count */
458+
448459
int flags;
449460
};
450461

@@ -453,6 +464,11 @@ static inline struct rvt_pd *ibpd_to_rvtpd(struct ib_pd *ibpd)
453464
return container_of(ibpd, struct rvt_pd, ibpd);
454465
}
455466

467+
static inline struct rvt_ah *ibah_to_rvtah(struct ib_ah *ibah)
468+
{
469+
return container_of(ibah, struct rvt_ah, ibah);
470+
}
471+
456472
static inline struct rvt_dev_info *ib_to_rvt(struct ib_device *ibdev)
457473
{
458474
return container_of(ibdev, struct rvt_dev_info, ibdev);
@@ -471,6 +487,7 @@ static inline void rvt_get_mr(struct rvt_mregion *mr)
471487

472488
int rvt_register_device(struct rvt_dev_info *rvd);
473489
void rvt_unregister_device(struct rvt_dev_info *rvd);
490+
int rvt_check_ah(struct ib_device *ibdev, struct ib_ah_attr *ah_attr);
474491
int rvt_rkey_ok(struct rvt_qp *qp, struct rvt_sge *sge,
475492
u32 len, u64 vaddr, u32 rkey, int acc);
476493
int rvt_lkey_ok(struct rvt_lkey_table *rkt, struct rvt_pd *pd,

0 commit comments

Comments
 (0)