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 */
18int 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
45bail:
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 */
56int 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