On 6/8/26 21:47, Shahyan Soltani wrote:
> Move struct amdgpu_wb and helpers out of the monolithic header amdgpu.h
> into its own dedicated header amdgpu_wb.h.
> 
> Move functions amdgpu_device_wb_get() and amdgpu_device_wb_free out of
> amdgpu_device.c into new dedicated amdgpu_wb.c file.
> 
> Update amdgpu/Makefile to build amdgpu_wb.o.
> 
> This is part of the ongoing effort to reduce the size of amdgpu.h into
> their own respective separate headers.
> 
> Signed-off-by: Shahyan Soltani <[email protected]>
> ---
>  drivers/gpu/drm/amd/amdgpu/Makefile        |   3 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h        |  68 +-------------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |  45 ----------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_wb.c     |  69 ++++++++++++++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_wb.h     | 100 +++++++++++++++++++++
>  5 files changed, 172 insertions(+), 113 deletions(-)
>  create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_wb.c
>  create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_wb.h
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile 
> b/drivers/gpu/drm/amd/amdgpu/Makefile
> index ee3574797bc2..e6deb24f73bb 100644
> --- a/drivers/gpu/drm/amd/amdgpu/Makefile
> +++ b/drivers/gpu/drm/amd/amdgpu/Makefile
> @@ -71,7 +71,8 @@ amdgpu-y += amdgpu_device.o amdgpu_reg_access.o 
> amdgpu_doorbell_mgr.o amdgpu_kms
>       amdgpu_fw_attestation.o amdgpu_securedisplay.o \
>       amdgpu_eeprom.o amdgpu_mca.o amdgpu_psp_ta.o amdgpu_lsdma.o \
>       amdgpu_ring_mux.o amdgpu_xcp.o amdgpu_seq64.o amdgpu_aca.o 
> amdgpu_dev_coredump.o \
> -     amdgpu_cper.o amdgpu_userq_fence.o amdgpu_eviction_fence.o amdgpu_ip.o
> +     amdgpu_cper.o amdgpu_userq_fence.o amdgpu_eviction_fence.o amdgpu_ip.o \
> +     amdgpu_wb.o
>  
>  amdgpu-$(CONFIG_PROC_FS) += amdgpu_fdinfo.o
>  
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index d7d8664854fd..9a714b4b59bc 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -112,6 +112,7 @@
>  #include "amdgpu_userq.h"
>  #include "amdgpu_eviction_fence.h"
>  #include "amdgpu_sa.h"
> +#include "amdgpu_wb.h"
>  #include "amdgpu_ip.h"
>  #if defined(CONFIG_DRM_AMD_ISP)
>  #include "amdgpu_isp.h"
> @@ -429,73 +430,6 @@ struct amdgpu_fpriv {
>  
>  int amdgpu_file_to_fpriv(struct file *filp, struct amdgpu_fpriv **fpriv);
>  
> -/*
> - * Writeback
> - */
> -#define AMDGPU_MAX_WB 1024   /* Reserve at most 1024 WB slots for 
> amdgpu-owned rings. */
> -
> -/**
> - * struct amdgpu_wb - This struct is used for small GPU memory allocation.
> - *
> - * This struct is used to allocate a small amount of GPU memory that can be
> - * used to shadow certain states into the memory. This is especially useful 
> for
> - * providing easy CPU access to some states without requiring register access
> - * (e.g., if some block is power gated, reading register may be problematic).
> - *
> - * Note: the term writeback was initially used because many of the amdgpu
> - * components had some level of writeback memory, and this struct initially
> - * described those components.
> - */
> -struct amdgpu_wb {
> -
> -     /**
> -      * @wb_obj:
> -      *
> -      * Buffer Object used for the writeback memory.
> -      */
> -     struct amdgpu_bo        *wb_obj;
> -
> -     /**
> -      * @wb:
> -      *
> -      * Pointer to the first writeback slot. In terms of CPU address
> -      * this value can be accessed directly by using the offset as an index.
> -      * For the GPU address, it is necessary to use gpu_addr and the offset.
> -      */
> -     uint32_t                *wb;
> -
> -     /**
> -      * @gpu_addr:
> -      *
> -      * Writeback base address in the GPU.
> -      */
> -     uint64_t                gpu_addr;
> -
> -     /**
> -      * @num_wb:
> -      *
> -      * Number of writeback slots reserved for amdgpu.
> -      */
> -     u32                     num_wb;
> -
> -     /**
> -      * @used:
> -      *
> -      * Track the writeback slot already used.
> -      */
> -     unsigned long           used[DIV_ROUND_UP(AMDGPU_MAX_WB, 
> BITS_PER_LONG)];
> -
> -     /**
> -      * @lock:
> -      *
> -      * Protects read and write of the used field array.
> -      */
> -     spinlock_t              lock;
> -};
> -
> -int amdgpu_device_wb_get(struct amdgpu_device *adev, u32 *wb);
> -void amdgpu_device_wb_free(struct amdgpu_device *adev, u32 wb);
> -
>  /*
>   * Benchmarking
>   */
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index 5ff224163bab..15a6a9010fc8 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -1058,51 +1058,6 @@ static int amdgpu_device_wb_init(struct amdgpu_device 
> *adev)
>       return 0;
>  }
>  
> -/**
> - * amdgpu_device_wb_get - Allocate a wb entry
> - *
> - * @adev: amdgpu_device pointer
> - * @wb: wb index
> - *
> - * Allocate a wb slot for use by the driver (all asics).
> - * Returns 0 on success or -EINVAL on failure.
> - */
> -int amdgpu_device_wb_get(struct amdgpu_device *adev, u32 *wb)
> -{
> -     unsigned long flags, offset;
> -
> -     spin_lock_irqsave(&adev->wb.lock, flags);
> -     offset = find_first_zero_bit(adev->wb.used, adev->wb.num_wb);
> -     if (offset < adev->wb.num_wb) {
> -             __set_bit(offset, adev->wb.used);
> -             spin_unlock_irqrestore(&adev->wb.lock, flags);
> -             *wb = offset << 3; /* convert to dw offset */
> -             return 0;
> -     } else {
> -             spin_unlock_irqrestore(&adev->wb.lock, flags);
> -             return -EINVAL;
> -     }
> -}
> -
> -/**
> - * amdgpu_device_wb_free - Free a wb entry
> - *
> - * @adev: amdgpu_device pointer
> - * @wb: wb index
> - *
> - * Free a wb slot allocated for use by the driver (all asics)
> - */
> -void amdgpu_device_wb_free(struct amdgpu_device *adev, u32 wb)
> -{
> -     unsigned long flags;
> -
> -     wb >>= 3;
> -     spin_lock_irqsave(&adev->wb.lock, flags);
> -     if (wb < adev->wb.num_wb)
> -             __clear_bit(wb, adev->wb.used);
> -     spin_unlock_irqrestore(&adev->wb.lock, flags);
> -}
> -
>  /**
>   * amdgpu_device_resize_fb_bar - try to resize FB BAR
>   *
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_wb.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_wb.c
> new file mode 100644
> index 000000000000..8e5f572077f3
> --- /dev/null
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_wb.c
> @@ -0,0 +1,69 @@
> +// SPDX-License-Identifier: GPL-2.0 OR MIT
> +/*
> + * Copyright 2026 Advanced Micro Devices, Inc.
> + *
> + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
> + */
> +#include "amdgpu.h"
> +#include "amdgpu_wb.h"
> +#include <linux/spinlock.h>
> +/**
> + * amdgpu_device_wb_get - Allocate a wb entry
> + *
> + * @adev: amdgpu_device pointer
> + * @wb: wb index
> + *
> + * Allocate a wb slot for use by the driver (all asics).
> + * Returns 0 on success or -EINVAL on failure.
> + */
> +int amdgpu_device_wb_get(struct amdgpu_device *adev, u32 *wb)

Drop the _device_ part from the function name now that this is a complete 
separate component.

You might also want to change the parameter from struct amdgpu_device to struct 
amdgpu_wb, not a must have but I think it would be cleaner.

Apart from those nit picks looks good to me.

Regards,
Christian.

> +{
> +     unsigned long flags, offset;
> +
> +     spin_lock_irqsave(&adev->wb.lock, flags);
> +     offset = find_first_zero_bit(adev->wb.used, adev->wb.num_wb);
> +     if (offset < adev->wb.num_wb) {
> +             __set_bit(offset, adev->wb.used);
> +             spin_unlock_irqrestore(&adev->wb.lock, flags);
> +             *wb = offset << 3; /* convert to dw offset */
> +             return 0;
> +     } else {
> +             spin_unlock_irqrestore(&adev->wb.lock, flags);
> +             return -EINVAL;
> +     }
> +}
> +
> +/**
> + * amdgpu_device_wb_free - Free a wb entry
> + *
> + * @adev: amdgpu_device pointer
> + * @wb: wb index
> + *
> + * Free a wb slot allocated for use by the driver (all asics)
> + */
> +void amdgpu_device_wb_free(struct amdgpu_device *adev, u32 wb)
> +{
> +     unsigned long flags;
> +
> +     wb >>= 3;
> +     spin_lock_irqsave(&adev->wb.lock, flags);
> +     if (wb < adev->wb.num_wb)
> +             __clear_bit(wb, adev->wb.used);
> +     spin_unlock_irqrestore(&adev->wb.lock, flags);
> +}
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_wb.h 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_wb.h
> new file mode 100644
> index 000000000000..dac9fc3f0004
> --- /dev/null
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_wb.h
> @@ -0,0 +1,100 @@
> +/* SPDX-License-Identifier: GPL-2.0 OR MIT
> + *
> + * Copyright 2026 Advanced Micro Devices, Inc.
> + *
> + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
> + */
> +#ifndef __AMDGPU_WB_H__
> +#define __AMDGPU_WB_H__
> +
> +#include <linux/types.h>
> +#include <linux/spinlock_types.h>
> +#include <linux/math.h>
> +
> +/*
> + * Writeback
> + */
> +#define AMDGPU_MAX_WB 1024   /* Reserve at most 1024 WB slots for 
> amdgpu-owned rings. */
> +
> +/**
> + * struct amdgpu_wb - This struct is used for small GPU memory allocation.
> + *
> + * This struct is used to allocate a small amount of GPU memory that can be
> + * used to shadow certain states into the memory. This is especially useful 
> for
> + * providing easy CPU access to some states without requiring register access
> + * (e.g., if some block is power gated, reading register may be problematic).
> + *
> + * Note: the term writeback was initially used because many of the amdgpu
> + * components had some level of writeback memory, and this struct initially
> + * described those components.
> + */
> +
> +struct amdgpu_bo;
> +struct amdgpu_device;
> +
> +struct amdgpu_wb {
> +
> +     /**
> +      * @wb_obj:
> +      *
> +      * Buffer Object used for the writeback memory.
> +      */
> +     struct amdgpu_bo        *wb_obj;
> +
> +     /**
> +      * @wb:
> +      *
> +      * Pointer to the first writeback slot. In terms of CPU address
> +      * this value can be accessed directly by using the offset as an index.
> +      * For the GPU address, it is necessary to use gpu_addr and the offset.
> +      */
> +     uint32_t                *wb;
> +
> +     /**
> +      * @gpu_addr:
> +      *
> +      * Writeback base address in the GPU.
> +      */
> +     uint64_t                gpu_addr;
> +
> +     /**
> +      * @num_wb:
> +      *
> +      * Number of writeback slots reserved for amdgpu.
> +      */
> +     u32                     num_wb;
> +
> +     /**
> +      * @used:
> +      *
> +      * Track the writeback slot already used.
> +      */
> +     unsigned long           used[DIV_ROUND_UP(AMDGPU_MAX_WB, 
> BITS_PER_LONG)];
> +
> +     /**
> +      * @lock:
> +      *
> +      * Protects read and write of the used field array.
> +      */
> +     spinlock_t              lock;
> +};
> +
> +int amdgpu_device_wb_get(struct amdgpu_device *adev, u32 *wb);
> +void amdgpu_device_wb_free(struct amdgpu_device *adev, u32 wb);
> +#endif

Reply via email to