From: Leon Romanovsky <leonro@xxxxxxxxxxxx> As a preparation to extension of rdma_restrack_root to provide software IDs, which will be per-type too. We convert the rdma_restrack_root from struct with arrays to array of structs. Signed-off-by: Leon Romanovsky <leonro@xxxxxxxxxxxx> --- drivers/infiniband/core/nldev.c | 12 +++---- drivers/infiniband/core/restrack.c | 55 ++++++++++++++++-------------- include/rdma/restrack.h | 5 +-- 3 files changed, 38 insertions(+), 34 deletions(-) diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c index df023116550f..1fd06ca18829 100644 --- a/drivers/infiniband/core/nldev.c +++ b/drivers/infiniband/core/nldev.c @@ -1076,7 +1076,7 @@ static int res_get_common_dumpit(struct sk_buff *skb, has_cap_net_admin = netlink_capable(cb->skb, CAP_NET_ADMIN); xa = rdma_dev_to_xa(device, res_type); - rdma_rt_read_lock(device, res_type); + rdma_rt_read_lock(xa); xa_for_each(xa, id, res) { if (idx < start) goto next; @@ -1098,13 +1098,13 @@ static int res_get_common_dumpit(struct sk_buff *skb, if (!entry_attr) { ret = -EMSGSIZE; rdma_restrack_put(res); - rdma_rt_read_unlock(device, res_type); + rdma_rt_read_unlock(xa); break; } - rdma_rt_read_unlock(device, res_type); + rdma_rt_read_unlock(xa); ret = fe->fill_res_func(skb, has_cap_net_admin, res, port); - rdma_rt_read_lock(device, res_type); + rdma_rt_read_lock(xa); /* * Return resource back, but it won't be released till * the &device->res.rwsem will be released for write. @@ -1125,7 +1125,7 @@ static int res_get_common_dumpit(struct sk_buff *skb, nla_nest_end(skb, entry_attr); next: idx++; } - rdma_rt_read_unlock(device, res_type); + rdma_rt_read_unlock(xa); nla_nest_end(skb, table_attr); nlmsg_end(skb, nlh); @@ -1143,7 +1143,7 @@ next: idx++; res_err: nla_nest_cancel(skb, table_attr); - rdma_rt_read_unlock(device, res_type); + rdma_rt_read_unlock(xa); err: nlmsg_cancel(skb, nlh); diff --git a/drivers/infiniband/core/restrack.c b/drivers/infiniband/core/restrack.c index 46ff8235e905..4a762eba26f0 100644 --- a/drivers/infiniband/core/restrack.c +++ b/drivers/infiniband/core/restrack.c @@ -46,17 +46,13 @@ struct rdma_restrack_root { */ struct rw_semaphore rwsem; /** - * @xa: Array of XArray structures to hold restrack entries. - * We want to use array of XArrays because insertion is type - * dependent. For types with xisiting unique ID (like QPN), - * we will insert to that unique index. For other types, - * we insert based on pointers and auto-allocate unique index. + * @xa: Array of XArray structure to hold restrack entries. */ - struct xarray xa[RDMA_RESTRACK_MAX]; + struct xarray xa; /** * #next_id: Next ID to support cyclic allocation */ - u32 next_id[RDMA_RESTRACK_MAX]; + u32 next_id; }; /** @@ -70,15 +66,16 @@ int rdma_restrack_init(struct ib_device *dev) struct rdma_restrack_root *rt; int i; - dev->res = kzalloc(sizeof(*rt), GFP_KERNEL); + dev->res = kcalloc(RDMA_RESTRACK_MAX, sizeof(*rt), GFP_KERNEL); if (!dev->res) return -ENOMEM; rt = dev->res; - for (i = 0 ; i < RDMA_RESTRACK_MAX; i++) - xa_init_flags(&rt->xa[i], XA_FLAGS_ALLOC); - init_rwsem(&rt->rwsem); + for (i = 0 ; i < RDMA_RESTRACK_MAX; i++) { + init_rwsem(&rt[i].rwsem); + xa_init_flags(&rt[i].xa, XA_FLAGS_ALLOC); + } return 0; } @@ -107,7 +104,7 @@ static const char *type2str(enum rdma_restrack_type type) struct xarray *rdma_dev_to_xa(struct ib_device *dev, enum rdma_restrack_type type) { - return &dev->res->xa[type]; + return &dev->res[type].xa; } EXPORT_SYMBOL(rdma_dev_to_xa); @@ -115,24 +112,28 @@ EXPORT_SYMBOL(rdma_dev_to_xa); /** * rdma_rt_read_lock() - Lock XArray for read, needed while iterating * with xa_for_each() - * @dev: IB device to work - * @type: resource track type + * @xa: XArray to lock */ -void rdma_rt_read_lock(struct ib_device *dev, enum rdma_restrack_type type) +void rdma_rt_read_lock(struct xarray *xa) { - down_read(&dev->res->rwsem); + struct rdma_restrack_root *rt = + container_of(xa, struct rdma_restrack_root, xa); + + down_read(&rt->rwsem); } EXPORT_SYMBOL(rdma_rt_read_lock); /** * rdma_rt_read_unlock() - Unlock XArray for read, needed while iterating * with xa_for_each() - * @dev: IB device to work - * @type: resource track type + * @xa: XArray to unlock */ -void rdma_rt_read_unlock(struct ib_device *dev, enum rdma_restrack_type type) +void rdma_rt_read_unlock(struct xarray *xa) { - up_read(&dev->res->rwsem); + struct rdma_restrack_root *rt = + container_of(xa, struct rdma_restrack_root, xa); + + up_read(&rt->rwsem); } EXPORT_SYMBOL(rdma_rt_read_unlock); @@ -201,14 +202,14 @@ int rdma_restrack_count(struct ib_device *dev, enum rdma_restrack_type type, unsigned long index = 0; u32 cnt = 0; - rdma_rt_read_lock(dev, type); + rdma_rt_read_lock(xa); xa_for_each(xa, index, e) { if (ns == &init_pid_ns || (!rdma_is_kernel_res(e) && ns == task_active_pid_ns(e->task))) cnt++; } - rdma_rt_read_unlock(dev, type); + rdma_rt_read_unlock(xa); return cnt; } EXPORT_SYMBOL(rdma_restrack_count); @@ -286,12 +287,12 @@ static void rdma_restrack_add(struct rdma_restrack_entry *res) if (!dev) return; - rt = dev->res; + rt = &dev->res[res->type]; xa = rdma_dev_to_xa(dev, res->type); kref_init(&res->kref); init_completion(&res->comp); - ret = rt_xa_alloc_cyclic(xa, &res->id, res, &rt->next_id[res->type]); + ret = rt_xa_alloc_cyclic(xa, &res->id, res, &rt->next_id); if (!ret) res->valid = true; } @@ -372,6 +373,7 @@ EXPORT_SYMBOL(rdma_restrack_put); void rdma_restrack_del(struct rdma_restrack_entry *res) { struct ib_device *dev = res_to_dev(res); + struct rdma_restrack_root *rt; struct xarray *xa; if (!res->valid) @@ -394,15 +396,16 @@ void rdma_restrack_del(struct rdma_restrack_entry *res) return; xa = rdma_dev_to_xa(dev, res->type); + rt = &dev->res[res->type]; rdma_restrack_put(res); wait_for_completion(&res->comp); - down_write(&dev->res->rwsem); + down_write(&rt->rwsem); xa_erase(xa, res->id); res->valid = false; - up_write(&dev->res->rwsem); + up_write(&rt->rwsem); out: if (res->task) { diff --git a/include/rdma/restrack.h b/include/rdma/restrack.h index 92d11c35221a..e9923965a3f8 100644 --- a/include/rdma/restrack.h +++ b/include/rdma/restrack.h @@ -159,6 +159,7 @@ struct rdma_restrack_entry *rdma_restrack_get_byid(struct ib_device *dev, u32 id); struct xarray *rdma_dev_to_xa(struct ib_device *dev, enum rdma_restrack_type type); -void rdma_rt_read_lock(struct ib_device *dev, enum rdma_restrack_type type); -void rdma_rt_read_unlock(struct ib_device *dev, enum rdma_restrack_type type); +void rdma_rt_read_lock(struct xarray *xa); +void rdma_rt_read_unlock(struct xarray *xa); + #endif /* _RDMA_RESTRACK_H_ */ -- 2.19.1