[Nouveau] [PATCH 34/44] drm/nouveau/gsp/r535: add support for rm alloc

Danilo Krummrich dakr at redhat.com
Mon Sep 25 17:44:13 UTC 2023


On 9/18/23 22:21, Ben Skeggs wrote:
> From: Ben Skeggs <bskeggs at redhat.com>
> 
> Adds the plumbing to be able to allocate and free RM objects, and
> implements RM client/device/subdevice allocation with it.
> 
> These will be used by subsequent patches.
> 
> Signed-off-by: Ben Skeggs <bskeggs at redhat.com>
> ---
>   .../gpu/drm/nouveau/include/nvkm/subdev/gsp.h | 131 +++++++++++++
>   .../common/sdk/nvidia/inc/class/cl0000.h      |  38 ++++
>   .../common/sdk/nvidia/inc/class/cl0080.h      |  43 ++++
>   .../common/sdk/nvidia/inc/class/cl2080.h      |  35 ++++
>   .../common/sdk/nvidia/inc/nvlimits.h          |  31 +++
>   .../nvidia/generated/g_rpc-structures.h       |  19 ++
>   .../nvidia/generated/g_sdk-structures.h       |  37 ++++
>   .../gpu/drm/nouveau/nvkm/subdev/gsp/r535.c    | 184 ++++++++++++++++++
>   8 files changed, 518 insertions(+)
>   create mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.54.03/common/sdk/nvidia/inc/class/cl0000.h
>   create mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.54.03/common/sdk/nvidia/inc/class/cl0080.h
>   create mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.54.03/common/sdk/nvidia/inc/class/cl2080.h
>   create mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.54.03/common/sdk/nvidia/inc/nvlimits.h
>   create mode 100644 drivers/gpu/drm/nouveau/include/nvrm/535.54.03/nvidia/generated/g_sdk-structures.h
> 
> diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
> index 8f0805474981..94b14f906df6 100644
> --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
> +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
> @@ -158,7 +158,24 @@ struct nvkm_gsp {
>   		void *(*rm_ctrl_get)(struct nvkm_gsp_object *, u32 cmd, u32 argc);
>   		void *(*rm_ctrl_push)(struct nvkm_gsp_object *, void *argv, u32 repc);
>   		void (*rm_ctrl_done)(struct nvkm_gsp_object *, void *repv);
> +
> +		void *(*rm_alloc_get)(struct nvkm_gsp_object *, u32 oclass, u32 argc);
> +		void *(*rm_alloc_push)(struct nvkm_gsp_object *, void *argv, u32 repc);
> +		void (*rm_alloc_done)(struct nvkm_gsp_object *, void *repv);
> +
> +		int (*rm_free)(struct nvkm_gsp_object *);
> +
> +		int (*client_ctor)(struct nvkm_gsp *, struct nvkm_gsp_client *);
> +		void (*client_dtor)(struct nvkm_gsp_client *);
> +
> +		int (*device_ctor)(struct nvkm_gsp_client *, struct nvkm_gsp_device *);
> +		void (*device_dtor)(struct nvkm_gsp_device *);
>   	} *rm;
> +
> +	struct {
> +		struct mutex mutex;;
> +		struct idr idr;
> +	} client_id;
>   };
>   
>   static inline bool
> @@ -247,6 +264,120 @@ nvkm_gsp_rm_ctrl_done(struct nvkm_gsp_object *object, void *repv)
>   	object->client->gsp->rm->rm_ctrl_done(object, repv);
>   }
>   
> +static inline void *
> +nvkm_gsp_rm_alloc_get(struct nvkm_gsp_object *parent, u32 handle, u32 oclass, u32 argc,
> +		      struct nvkm_gsp_object *object)
> +{
> +	struct nvkm_gsp_client *client = parent->client;
> +	struct nvkm_gsp *gsp = client->gsp;
> +	void *argv;
> +
> +	object->client = parent->client;
> +	object->parent = parent;
> +	object->handle = handle;
> +
> +	argv = gsp->rm->rm_alloc_get(object, oclass, argc);
> +	if (IS_ERR_OR_NULL(argv)) {
> +		object->client = NULL;

Why do we need to set ->client to NULL here? What about ->parent and ->handle?

> +		return argv;
> +	}
> +
> +	return argv;
> +}
> +
> +static inline void *
> +nvkm_gsp_rm_alloc_push(struct nvkm_gsp_object *object, void *argv, u32 repc)
> +{
> +	void *repv = object->client->gsp->rm->rm_alloc_push(object, argv, repc);
> +
> +	if (IS_ERR(repv))
> +		object->client = NULL;
> +
> +	return repv;
> +}
> +
> +static inline int
> +nvkm_gsp_rm_alloc_wr(struct nvkm_gsp_object *object, void *argv)
> +{
> +	void *repv = nvkm_gsp_rm_alloc_push(object, argv, 0);
> +
> +	if (IS_ERR(repv))
> +		return PTR_ERR(repv);
> +
> +	return 0;
> +}
> +
> +static inline void
> +nvkm_gsp_rm_alloc_done(struct nvkm_gsp_object *object, void *repv)
> +{
> +	object->client->gsp->rm->rm_alloc_done(object, repv);
> +}
> +
> +static inline int
> +nvkm_gsp_rm_alloc(struct nvkm_gsp_object *parent, u32 handle, u32 oclass, u32 argc,
> +		  struct nvkm_gsp_object *object)
> +{
> +	void *argv = nvkm_gsp_rm_alloc_get(parent, handle, oclass, argc, object);
> +
> +	if (IS_ERR_OR_NULL(argv))
> +		return argv ? PTR_ERR(argv) : -EIO;
> +
> +	return nvkm_gsp_rm_alloc_wr(object, argv);
> +}
> +
> +static inline int
> +nvkm_gsp_rm_free(struct nvkm_gsp_object *object)
> +{
> +	if (object->client)
> +		return object->client->gsp->rm->rm_free(object);
> +
> +	return 0;
> +}
> +
> +static inline int
> +nvkm_gsp_client_ctor(struct nvkm_gsp *gsp, struct nvkm_gsp_client *client)
> +{
> +	if (WARN_ON(!gsp->rm))
> +		return -ENOSYS;
> +
> +	return gsp->rm->client_ctor(gsp, client);
> +}
> +
> +static inline void
> +nvkm_gsp_client_dtor(struct nvkm_gsp_client *client)
> +{
> +	if (client->gsp)
> +		client->gsp->rm->client_dtor(client);
> +}
> +
> +static inline int
> +nvkm_gsp_device_ctor(struct nvkm_gsp_client *client, struct nvkm_gsp_device *device)
> +{
> +	return client->gsp->rm->device_ctor(client, device);
> +}
> +
> +static inline void
> +nvkm_gsp_device_dtor(struct nvkm_gsp_device *device)
> +{
> +	if (device->object.client)
> +		device->object.client->gsp->rm->device_dtor(device);
> +}
> +
> +static inline int
> +nvkm_gsp_client_device_ctor(struct nvkm_gsp *gsp,
> +			    struct nvkm_gsp_client *client, struct nvkm_gsp_device *device)
> +{
> +	int ret = nvkm_gsp_client_ctor(gsp, client);
> +
> +	if (ret == 0) {
> +		ret = nvkm_gsp_device_ctor(client, device);
> +		if (ret)
> +			nvkm_gsp_client_dtor(client);
> +	}
> +
> +	return ret;
> +}
> +
>   int gv100_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);
>   int tu102_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);
>   int tu116_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);
> diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.54.03/common/sdk/nvidia/inc/class/cl0000.h b/drivers/gpu/drm/nouveau/include/nvrm/535.54.03/common/sdk/nvidia/inc/class/cl0000.h
> new file mode 100644
> index 000000000000..dfb3b3e0c45b
> --- /dev/null
> +++ b/drivers/gpu/drm/nouveau/include/nvrm/535.54.03/common/sdk/nvidia/inc/class/cl0000.h
> @@ -0,0 +1,38 @@
> +#ifndef __src_common_sdk_nvidia_inc_class_cl0000_h__
> +#define __src_common_sdk_nvidia_inc_class_cl0000_h__
> +#include <nvrm/535.54.03/common/sdk/nvidia/inc/nvlimits.h>
> +
> +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.54.03 */
> +
> +/*
> + * SPDX-FileCopyrightText: Copyright (c) 2001-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
> + * SPDX-License-Identifier: MIT
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + */
> +
> +#define NV01_ROOT        (0x0U) /* finn: Evaluated from "NV0000_ALLOC_PARAMETERS_MESSAGE_ID" */
> +
> +typedef struct NV0000_ALLOC_PARAMETERS {
> +    NvHandle hClient; /* CORERM-2934: hClient must remain the first member until all allocations use these params */
> +    NvU32    processID;
> +    char     processName[NV_PROC_NAME_MAX_LENGTH];
> +} NV0000_ALLOC_PARAMETERS;
> +
> +#endif
> diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.54.03/common/sdk/nvidia/inc/class/cl0080.h b/drivers/gpu/drm/nouveau/include/nvrm/535.54.03/common/sdk/nvidia/inc/class/cl0080.h
> new file mode 100644
> index 000000000000..aeab857b1e50
> --- /dev/null
> +++ b/drivers/gpu/drm/nouveau/include/nvrm/535.54.03/common/sdk/nvidia/inc/class/cl0080.h
> @@ -0,0 +1,43 @@
> +#ifndef __src_common_sdk_nvidia_inc_class_cl0080_h__
> +#define __src_common_sdk_nvidia_inc_class_cl0080_h__
> +
> +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.54.03 */
> +
> +/*
> + * SPDX-FileCopyrightText: Copyright (c) 2001-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
> + * SPDX-License-Identifier: MIT
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + */
> +
> +#define NV01_DEVICE_0      (0x80U) /* finn: Evaluated from "NV0080_ALLOC_PARAMETERS_MESSAGE_ID" */
> +
> +typedef struct NV0080_ALLOC_PARAMETERS {
> +    NvU32    deviceId;
> +    NvHandle hClientShare;
> +    NvHandle hTargetClient;
> +    NvHandle hTargetDevice;
> +    NvV32    flags;
> +    NV_DECLARE_ALIGNED(NvU64 vaSpaceSize, 8);
> +    NV_DECLARE_ALIGNED(NvU64 vaStartInternal, 8);
> +    NV_DECLARE_ALIGNED(NvU64 vaLimitInternal, 8);
> +    NvV32    vaMode;
> +} NV0080_ALLOC_PARAMETERS;
> +
> +#endif
> diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.54.03/common/sdk/nvidia/inc/class/cl2080.h b/drivers/gpu/drm/nouveau/include/nvrm/535.54.03/common/sdk/nvidia/inc/class/cl2080.h
> new file mode 100644
> index 000000000000..a0106cd77cd9
> --- /dev/null
> +++ b/drivers/gpu/drm/nouveau/include/nvrm/535.54.03/common/sdk/nvidia/inc/class/cl2080.h
> @@ -0,0 +1,35 @@
> +#ifndef __src_common_sdk_nvidia_inc_class_cl2080_h__
> +#define __src_common_sdk_nvidia_inc_class_cl2080_h__
> +
> +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.54.03 */
> +
> +/*
> + * SPDX-FileCopyrightText: Copyright (c) 2002-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
> + * SPDX-License-Identifier: MIT
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + */
> +
> +#define NV20_SUBDEVICE_0      (0x2080U) /* finn: Evaluated from "NV2080_ALLOC_PARAMETERS_MESSAGE_ID" */
> +
> +typedef struct NV2080_ALLOC_PARAMETERS {
> +    NvU32 subDeviceId;
> +} NV2080_ALLOC_PARAMETERS;
> +
> +#endif
> diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.54.03/common/sdk/nvidia/inc/nvlimits.h b/drivers/gpu/drm/nouveau/include/nvrm/535.54.03/common/sdk/nvidia/inc/nvlimits.h
> new file mode 100644
> index 000000000000..12393c8aaf29
> --- /dev/null
> +++ b/drivers/gpu/drm/nouveau/include/nvrm/535.54.03/common/sdk/nvidia/inc/nvlimits.h
> @@ -0,0 +1,31 @@
> +#ifndef __src_common_sdk_nvidia_inc_nvlimits_h__
> +#define __src_common_sdk_nvidia_inc_nvlimits_h__
> +
> +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.54.03 */
> +
> +/*
> + * SPDX-FileCopyrightText: Copyright (c) 2017 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
> + * SPDX-License-Identifier: MIT
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + */
> +
> +#define NV_PROC_NAME_MAX_LENGTH 100U
> +
> +#endif
> diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.54.03/nvidia/generated/g_rpc-structures.h b/drivers/gpu/drm/nouveau/include/nvrm/535.54.03/nvidia/generated/g_rpc-structures.h
> index 1ae0a97df392..38d42cdbc9cb 100644
> --- a/drivers/gpu/drm/nouveau/include/nvrm/535.54.03/nvidia/generated/g_rpc-structures.h
> +++ b/drivers/gpu/drm/nouveau/include/nvrm/535.54.03/nvidia/generated/g_rpc-structures.h
> @@ -1,5 +1,6 @@
>   #ifndef __src_nvidia_generated_g_rpc_structures_h__
>   #define __src_nvidia_generated_g_rpc_structures_h__
> +#include <nvrm/535.54.03/nvidia/generated/g_sdk-structures.h>
>   
>   /* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.54.03 */
>   
> @@ -26,6 +27,11 @@
>    * DEALINGS IN THE SOFTWARE.
>    */
>   
> +typedef struct rpc_free_v03_00
> +{
> +    NVOS00_PARAMETERS_v03_00 params;
> +} rpc_free_v03_00;
> +
>   typedef struct rpc_unloading_guest_driver_v1F_07
>   {
>       NvBool     bInPMTransition;
> @@ -33,6 +39,19 @@ typedef struct rpc_unloading_guest_driver_v1F_07
>       NvU32      newLevel;
>   } rpc_unloading_guest_driver_v1F_07;
>   
> +typedef struct rpc_gsp_rm_alloc_v03_00
> +{
> +    NvHandle   hClient;
> +    NvHandle   hParent;
> +    NvHandle   hObject;
> +    NvU32      hClass;
> +    NvU32      status;
> +    NvU32      paramsSize;
> +    NvU32      flags;
> +    NvU8       reserved[4];
> +    NvU8       params[];
> +} rpc_gsp_rm_alloc_v03_00;
> +
>   typedef struct rpc_gsp_rm_control_v03_00
>   {
>       NvHandle   hClient;
> diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.54.03/nvidia/generated/g_sdk-structures.h b/drivers/gpu/drm/nouveau/include/nvrm/535.54.03/nvidia/generated/g_sdk-structures.h
> new file mode 100644
> index 000000000000..4ed66c13bb91
> --- /dev/null
> +++ b/drivers/gpu/drm/nouveau/include/nvrm/535.54.03/nvidia/generated/g_sdk-structures.h
> @@ -0,0 +1,37 @@
> +#ifndef __src_nvidia_generated_g_sdk_structures_h__
> +#define __src_nvidia_generated_g_sdk_structures_h__
> +
> +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.54.03 */
> +
> +/*
> + * SPDX-FileCopyrightText: Copyright (c) 2008-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
> + * SPDX-License-Identifier: MIT
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + */
> +
> +typedef struct NVOS00_PARAMETERS_v03_00
> +{
> +    NvHandle   hRoot;
> +    NvHandle   hObjectParent;
> +    NvHandle   hObjectOld;
> +    NvV32      status;
> +} NVOS00_PARAMETERS_v03_00;
> +
> +#endif
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c
> index 0fafb8f1e88d..c1a5f0696e85 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c
> @@ -28,6 +28,9 @@
>   #include <nvfw/fw.h>
>   
>   #include <nvrm/nvtypes.h>
> +#include <nvrm/535.54.03/common/sdk/nvidia/inc/class/cl0000.h>
> +#include <nvrm/535.54.03/common/sdk/nvidia/inc/class/cl0080.h>
> +#include <nvrm/535.54.03/common/sdk/nvidia/inc/class/cl2080.h>
>   #include <nvrm/535.54.03/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080gpu.h>
>   #include <nvrm/535.54.03/common/shared/msgq/inc/msgq/msgq_priv.h>
>   #include <nvrm/535.54.03/common/uproc/os/common/include/libos_init_args.h>
> @@ -354,6 +357,169 @@ r535_gsp_rpc_send(struct nvkm_gsp *gsp, void *argv, bool wait, u32 repc)
>   	return repv;
>   }
>   
> +static void
> +r535_gsp_device_dtor(struct nvkm_gsp_device *device)
> +{
> +	nvkm_gsp_rm_free(&device->subdevice);
> +	nvkm_gsp_rm_free(&device->object);
> +}
> +
> +static int
> +r535_gsp_subdevice_ctor(struct nvkm_gsp_device *device)
> +{
> +	NV2080_ALLOC_PARAMETERS *args;
> +
> +	return nvkm_gsp_rm_alloc(&device->object, 0x5d1d0000, NV20_SUBDEVICE_0, sizeof(*args),
> +				 &device->subdevice);
> +}
> +
> +static int
> +r535_gsp_device_ctor(struct nvkm_gsp_client *client, struct nvkm_gsp_device *device)
> +{
> +	NV0080_ALLOC_PARAMETERS *args;
> +	int ret;
> +
> +	args = nvkm_gsp_rm_alloc_get(&client->object, 0xde1d0000, NV01_DEVICE_0, sizeof(*args),

What is this handle (0xde1d0000)?

> +				     &device->object);
> +	if (IS_ERR(args))
> +		return PTR_ERR(args);
> +
> +	args->hClientShare = client->object.handle;

Is the handle used for anything else than this?

> +
> +	ret = nvkm_gsp_rm_alloc_wr(&device->object, args);
> +	if (ret)
> +		return ret;
> +
> +	ret = r535_gsp_subdevice_ctor(device);
> +	if (ret)
> +		nvkm_gsp_rm_free(&device->object);
> +
> +	return ret;
> +}
> +
> +static void
> +r535_gsp_client_dtor(struct nvkm_gsp_client *client)
> +{
> +	struct nvkm_gsp *gsp = client->gsp;
> +
> +	nvkm_gsp_rm_free(&client->object);
> +
> +	mutex_lock(&gsp->client_id.mutex);
> +	idr_remove(&gsp->client_id.idr, client->object.handle & 0xffff);
> +	mutex_unlock(&gsp->client_id.mutex);

Should use xarray instead, this also gets us rid of the dedicated mutex.

> +
> +	client->gsp = NULL;
> +}
> +
> +static int
> +r535_gsp_client_ctor(struct nvkm_gsp *gsp, struct nvkm_gsp_client *client)
> +{
> +	NV0000_ALLOC_PARAMETERS *args;
> +	int ret;
> +
> +	mutex_lock(&gsp->client_id.mutex);
> +	ret = idr_alloc(&gsp->client_id.idr, client, 0, 0xffff + 1, GFP_KERNEL);
> +	mutex_unlock(&gsp->client_id.mutex);
> +	if (ret < 0)
> +		return ret;
> +
> +	client->gsp = gsp;
> +	client->object.client = client;
> +
> +	args = nvkm_gsp_rm_alloc_get(&client->object, 0xc1d00000 | ret, NV01_ROOT, sizeof(*args),
> +				     &client->object);
> +	if (IS_ERR(args)) {
> +		r535_gsp_client_dtor(client);
> +		return ret;
> +	}
> +
> +	args->hClient = client->object.handle;

Same as above, used anywhere else?

> +	args->processID = ~0;
> +
> +	ret = nvkm_gsp_rm_alloc_wr(&client->object, args);
> +	if (ret) {
> +		r535_gsp_client_dtor(client);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +r535_gsp_rpc_rm_free(struct nvkm_gsp_object *object)
> +{
> +	struct nvkm_gsp_client *client = object->client;
> +	struct nvkm_gsp *gsp = client->gsp;
> +	rpc_free_v03_00 *rpc;
> +
> +	nvkm_debug(&gsp->subdev, "cli:0x%08x obj:0x%08x free\n",
> +		   client->object.handle, object->handle);
> +
> +	rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_FREE, sizeof(*rpc));
> +	if (WARN_ON(IS_ERR_OR_NULL(rpc)))
> +		return -EIO;
> +
> +	rpc->params.hRoot = client->object.handle;
> +	rpc->params.hObjectParent = 0;
> +	rpc->params.hObjectOld = object->handle;
> +	return nvkm_gsp_rpc_wr(gsp, rpc, true);
> +}
> +
> +static void
> +r535_gsp_rpc_rm_alloc_done(struct nvkm_gsp_object *object, void *repv)
> +{
> +	rpc_gsp_rm_alloc_v03_00 *rpc = container_of(repv, typeof(*rpc), params);
> +
> +	nvkm_gsp_rpc_done(object->client->gsp, rpc);
> +}
> +
> +static void *
> +r535_gsp_rpc_rm_alloc_push(struct nvkm_gsp_object *object, void *argv, u32 repc)
> +{
> +	rpc_gsp_rm_alloc_v03_00 *rpc = container_of(argv, typeof(*rpc), params);
> +	struct nvkm_gsp *gsp = object->client->gsp;
> +	void *ret;
> +
> +	rpc = nvkm_gsp_rpc_push(gsp, rpc, true, sizeof(*rpc) + repc);
> +	if (IS_ERR_OR_NULL(rpc))
> +		return rpc;
> +
> +	if (rpc->status) {
> +		nvkm_error(&gsp->subdev, "RM_ALLOC: 0x%x\n", rpc->status);
> +		ret = ERR_PTR(-EINVAL);
> +	} else {
> +		ret = repc ? rpc->params : NULL;
> +	}
> +
> +	if (IS_ERR_OR_NULL(ret))
> +		nvkm_gsp_rpc_done(gsp, rpc);
> +
> +	return ret;
> +}
> +
> +static void *
> +r535_gsp_rpc_rm_alloc_get(struct nvkm_gsp_object *object, u32 oclass, u32 argc)
> +{
> +	struct nvkm_gsp_client *client = object->client;
> +	struct nvkm_gsp *gsp = client->gsp;
> +	rpc_gsp_rm_alloc_v03_00 *rpc;
> +
> +	nvkm_debug(&gsp->subdev, "cli:0x%08x obj:0x%08x new obj:0x%08x cls:0x%08x argc:%d\n",
> +		   client->object.handle, object->parent->handle, object->handle, oclass, argc);
> +
> +	rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_GSP_RM_ALLOC, sizeof(*rpc) + argc);
> +	if (IS_ERR(rpc))
> +		return rpc;
> +
> +	rpc->hClient = client->object.handle;
> +	rpc->hParent = object->parent->handle;
> +	rpc->hObject = object->handle;
> +	rpc->hClass = oclass;
> +	rpc->status = 0;
> +	rpc->paramsSize = argc;
> +	return rpc->params;
> +}
> +
>   static void
>   r535_gsp_rpc_rm_ctrl_done(struct nvkm_gsp_object *object, void *repv)
>   {
> @@ -509,6 +675,18 @@ r535_gsp_rm = {
>   	.rm_ctrl_get = r535_gsp_rpc_rm_ctrl_get,
>   	.rm_ctrl_push = r535_gsp_rpc_rm_ctrl_push,
>   	.rm_ctrl_done = r535_gsp_rpc_rm_ctrl_done,
> +
> +	.rm_alloc_get = r535_gsp_rpc_rm_alloc_get,
> +	.rm_alloc_push = r535_gsp_rpc_rm_alloc_push,
> +	.rm_alloc_done = r535_gsp_rpc_rm_alloc_done,
> +
> +	.rm_free = r535_gsp_rpc_rm_free,
> +
> +	.client_ctor = r535_gsp_client_ctor,
> +	.client_dtor = r535_gsp_client_dtor,
> +
> +	.device_ctor = r535_gsp_device_ctor,
> +	.device_dtor = r535_gsp_device_dtor,
>   };
>   
>   static int
> @@ -1473,6 +1651,9 @@ r535_gsp_dtor_fws(struct nvkm_gsp *gsp)
>   void
>   r535_gsp_dtor(struct nvkm_gsp *gsp)
>   {
> +	idr_destroy(&gsp->client_id.idr);
> +	mutex_destroy(&gsp->client_id.mutex);
> +
>   	nvkm_gsp_radix3_dtor(gsp, &gsp->radix3);
>   	nvkm_gsp_mem_dtor(gsp, &gsp->sig);
>   	nvkm_firmware_dtor(&gsp->fw);
> @@ -1601,6 +1782,9 @@ r535_gsp_oneinit(struct nvkm_gsp *gsp)
>   
>   	nvkm_falcon_wr32(&gsp->falcon, 0x040, lower_32_bits(gsp->libos.addr));
>   	nvkm_falcon_wr32(&gsp->falcon, 0x044, upper_32_bits(gsp->libos.addr));
> +
> +	mutex_init(&gsp->client_id.mutex);
> +	idr_init(&gsp->client_id.idr);
>   	return 0;
>   }
>   



More information about the Nouveau mailing list