GNU Linux-libre 5.19-rc6-gnu
[releases.git] / drivers / infiniband / sw / rdmavt / pd.c
1 // SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause
2 /*
3  * Copyright(c) 2016 Intel Corporation.
4  */
5
6 #include <linux/slab.h>
7 #include "pd.h"
8
9 /**
10  * rvt_alloc_pd - allocate a protection domain
11  * @ibpd: PD
12  * @udata: optional user data
13  *
14  * Allocate and keep track of a PD.
15  *
16  * Return: 0 on success
17  */
18 int rvt_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
19 {
20         struct ib_device *ibdev = ibpd->device;
21         struct rvt_dev_info *dev = ib_to_rvt(ibdev);
22         struct rvt_pd *pd = ibpd_to_rvtpd(ibpd);
23         int ret = 0;
24
25         /*
26          * While we could continue allocating protecetion domains, being
27          * constrained only by system resources. The IBTA spec defines that
28          * there is a max_pd limit that can be set and we need to check for
29          * that.
30          */
31
32         spin_lock(&dev->n_pds_lock);
33         if (dev->n_pds_allocated == dev->dparms.props.max_pd) {
34                 spin_unlock(&dev->n_pds_lock);
35                 ret = -ENOMEM;
36                 goto bail;
37         }
38
39         dev->n_pds_allocated++;
40         spin_unlock(&dev->n_pds_lock);
41
42         /* ib_alloc_pd() will initialize pd->ibpd. */
43         pd->user = !!udata;
44
45 bail:
46         return ret;
47 }
48
49 /**
50  * rvt_dealloc_pd - Free PD
51  * @ibpd: Free up PD
52  * @udata: Valid user data or NULL for kernel object
53  *
54  * Return: always 0
55  */
56 int rvt_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
57 {
58         struct rvt_dev_info *dev = ib_to_rvt(ibpd->device);
59
60         spin_lock(&dev->n_pds_lock);
61         dev->n_pds_allocated--;
62         spin_unlock(&dev->n_pds_lock);
63         return 0;
64 }