[PATCH 3/3] drm/amdgpu: Reserve shared memory on VRAM for SR-IOV

Deucher, Alexander Alexander.Deucher at amd.com
Wed Sep 27 15:16:24 UTC 2017


> -----Original Message-----
> From: amd-gfx [mailto:amd-gfx-bounces at lists.freedesktop.org] On Behalf
> Of Horace Chen
> Sent: Wednesday, September 27, 2017 5:24 AM
> To: amd-gfx at lists.freedesktop.org
> Cc: Deucher, Alexander; Chen, Horace
> Subject: [PATCH 3/3] drm/amdgpu: Reserve shared memory on VRAM for
> SR-IOV
> 
>  SR-IOV need to reserve a piece of shared VRAM to exchange data
> betweem PF and VF. The start address and size of the shared mem
> are passed to guest through VBIOS structure VRAM_UsageByFirmware.
> 
> VRAM_UsageByFirmware is a general feature in VBIOS, it indicates that
> VBIOS need to reserve a piece of memory on the VRAM.
> 
> Signed-off-by: Horace Chen <horace.chen at amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h          | 17 ++++++++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c | 18 +++++++-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c   | 62
> ++++++++++++++++++++++++++++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c      |  9 ++++
>  4 files changed, 105 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index a5b0b67..ac53dba 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -1380,6 +1380,21 @@ struct amdgpu_atcs {
>  };
> 
>  /*
> + * Firmware VRAM reservation
> + */
> +#define KB_TO_BYTE(x)                           ((x) << 10)
> +#define BYTE_TO_KB(x)                           ((x) >> 10)
> +
> +struct amdgpu_fw_vram_usage {
> +	uint32_t start_address_in_kb;
> +	uint16_t size_in_kb;

Just store these in bytes.  Do the conversion when you read them out of the vbios table.  That's more consistent with how we start addresses elsewhere in the driver.

Alex

> +	struct amdgpu_bo *reserved_bo;
> +	volatile uint32_t *va;
> +};
> +
> +int amdgpu_fw_reserve_vram_init(struct amdgpu_device *adev);
> +
> +/*
>   * CGS
>   */
>  struct cgs_device *amdgpu_cgs_create_device(struct amdgpu_device
> *adev);
> @@ -1588,6 +1603,8 @@ struct amdgpu_device {
>  	struct delayed_work     late_init_work;
> 
>  	struct amdgpu_virt	virt;
> +	/* firmware VRAM reservation */
> +	struct amdgpu_fw_vram_usage fw_vram_usage;
> 
>  	/* link all shadow bo */
>  	struct list_head                shadow_list;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
> index ce44358..56bfddf 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
> @@ -1807,6 +1807,8 @@ int amdgpu_atombios_allocate_fb_scratch(struct
> amdgpu_device *adev)
>  	uint16_t data_offset;
>  	int usage_bytes = 0;
>  	struct _ATOM_VRAM_USAGE_BY_FIRMWARE *firmware_usage;
> +	uint32_t start_addr;
> +	uint16_t size;
> 
>  	if (amdgpu_atom_parse_data_header(ctx, index, NULL, NULL, NULL,
> &data_offset)) {
>  		firmware_usage = (struct
> _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset);
> @@ -1815,7 +1817,21 @@ int amdgpu_atombios_allocate_fb_scratch(struct
> amdgpu_device *adev)
>  			  le32_to_cpu(firmware_usage-
> >asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware),
>  			  le16_to_cpu(firmware_usage-
> >asFirmwareVramReserveInfo[0].usFirmwareUseInKb));
> 
> -		usage_bytes = le16_to_cpu(firmware_usage-
> >asFirmwareVramReserveInfo[0].usFirmwareUseInKb) * 1024;
> +		start_addr = firmware_usage-
> >asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware;
> +		size = firmware_usage-
> >asFirmwareVramReserveInfo[0].usFirmwareUseInKb;
> +
> +		if ((uint32_t)(start_addr &
> ATOM_VRAM_OPERATION_FLAGS_MASK) ==
> +
> 	(uint32_t)(ATOM_VRAM_BLOCK_SRIOV_MSG_SHARE_RESERVATIO
> N <<
> +			ATOM_VRAM_OPERATION_FLAGS_SHIFT)) {
> +			/* Firmware request VRAM reservation for SR-IOV */
> +			adev->fw_vram_usage.start_address_in_kb =
> +			    start_addr &
> (~ATOM_VRAM_OPERATION_FLAGS_MASK);
> +			adev->fw_vram_usage.size_in_kb = size;
> +			/* Use the default scratch size */
> +			usage_bytes = 0;
> +		} else {
> +			usage_bytes = le16_to_cpu(firmware_usage-
> >asFirmwareVramReserveInfo[0].usFirmwareUseInKb) * 1024;
> +		}
>  	}
>  	ctx->scratch_size_bytes = 0;
>  	if (usage_bytes == 0)
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index a86d856..3da87cc 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -658,6 +658,66 @@ void amdgpu_gart_location(struct amdgpu_device
> *adev, struct amdgpu_mc *mc)
>  }
> 
>  /*
> + * Firmware Reservation function
> + */
> +/**
> + * amdgpu_fw_reserve_vram_fini - free fw reserved vram
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * free fw reserved vram if it is reserved.
> + */
> +void amdgpu_fw_reserve_vram_fini(struct amdgpu_device *adev)
> +{
> +
> +	if (adev->fw_vram_usage.reserved_bo == NULL)
> +		return;
> +
> +	amdgpu_bo_free_vram_specified(&adev-
> >fw_vram_usage.reserved_bo, NULL,
> +		(void **)&adev->fw_vram_usage.va);
> +	adev->fw_vram_usage.reserved_bo = NULL;
> +}
> +
> +/**
> + * amdgpu_fw_reserve_vram_fini - create bo vram reservation from fw
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * create bo vram reservation from fw.
> + */
> +int amdgpu_fw_reserve_vram_init(struct amdgpu_device *adev)
> +{
> +	int r = 0;
> +	u64 gpu_addr;
> +	u64 vram_size = adev->mc.visible_vram_size;
> +	u64 start_addr;
> +	u32 size;
> +
> +	adev->fw_vram_usage.va = NULL;
> +	adev->fw_vram_usage.reserved_bo = NULL;
> +
> +	if (adev->fw_vram_usage.size_in_kb > 0 &&
> +		KB_TO_BYTE((u64)adev->fw_vram_usage.size_in_kb) <=
> vram_size) {
> +
> +		start_addr =
> +		    KB_TO_BYTE((u64)adev-
> >fw_vram_usage.start_address_in_kb);
> +		size = KB_TO_BYTE((u64)adev->fw_vram_usage.size_in_kb);
> +
> +		r = amdgpu_bo_create_vram_specified(adev,
> +			    start_addr, size, PAGE_SIZE,
> +			    AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED
> |
> +			    AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
> +			    &adev->fw_vram_usage.reserved_bo,
> +			    &gpu_addr, (void **)&adev->fw_vram_usage.va);
> +		if (r)
> +			dev_info(adev->dev, "Reserve VRAM for firmware
> failed");
> +	}
> +
> +	return r;
> +}
> +
> +
> +/*
>   * GPU helpers function.
>   */
>  /**
> @@ -2055,6 +2115,7 @@ int amdgpu_device_init(struct amdgpu_device
> *adev,
>  	adev->vm_manager.vm_pte_num_rings = 0;
>  	adev->gart.gart_funcs = NULL;
>  	adev->fence_context =
> dma_fence_context_alloc(AMDGPU_MAX_RINGS);
> +	adev->fw_vram_usage.size_in_kb = 0;

No need to set this explicitly.   The device structure is already initialized to 0 at allocation time.

> 
>  	adev->smc_rreg = &amdgpu_invalid_rreg;
>  	adev->smc_wreg = &amdgpu_invalid_wreg;
> @@ -2331,6 +2392,7 @@ void amdgpu_device_fini(struct amdgpu_device
> *adev)
>  	/* evict vram memory */
>  	amdgpu_bo_evict_vram(adev);
>  	amdgpu_ib_pool_fini(adev);
> +	amdgpu_fw_reserve_vram_fini(adev);
>  	amdgpu_fence_driver_fini(adev);
>  	amdgpu_fbdev_fini(adev);
>  	r = amdgpu_fini(adev);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index 1086f03..a5253cf 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -1256,6 +1256,15 @@ int amdgpu_ttm_init(struct amdgpu_device
> *adev)
>  	/* Change the size here instead of the init above so only lpfn is
> affected */
>  	amdgpu_ttm_set_active_vram_size(adev, adev-
> >mc.visible_vram_size);
> 
> +	/*
> +	 *The reserved vram for firmware must be pinned to the specified
> +	 *place on the VRAM, so reserve it early.
> +	 */
> +	r = amdgpu_fw_reserve_vram_init(adev);
> +	if (r) {
> +		return r;
> +	}
> +
>  	r = amdgpu_bo_create_kernel(adev, adev->mc.stolen_size,
> PAGE_SIZE,
>  				    AMDGPU_GEM_DOMAIN_VRAM,
>  				    &adev->stolen_vga_memory,
> --
> 2.7.4
> 
> _______________________________________________
> amd-gfx mailing list
> amd-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx


More information about the amd-gfx mailing list