xref: /openbmc/linux/drivers/infiniband/sw/rdmavt/pd.c (revision 2a598d0b)
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 }
65