lkml.org 
[lkml]   [2020]   [Aug]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.8 35/64] drm/amdgpu/debugfs: fix ref count leak when pm_runtime_get_sync fails
    Date
    From: Alex Deucher <alexander.deucher@amd.com>

    [ Upstream commit 9eee152aab56d374edb9ad21b3db05f5cdda2fe6 ]

    The call to pm_runtime_get_sync increments the counter even in case of
    failure, leading to incorrect ref count.
    In case of failure, decrement the ref count before returning.

    Acked-by: Evan Quan <evan.quan@amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 95 +++++++++++++++------
    1 file changed, 70 insertions(+), 25 deletions(-)

    diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
    index a414da22a359c..386b979e08522 100644
    --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
    +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
    @@ -223,12 +223,16 @@ static int amdgpu_debugfs_process_reg_op(bool read, struct file *f,
    *pos &= (1UL << 22) - 1;

    r = pm_runtime_get_sync(adev->ddev->dev);
    - if (r < 0)
    + if (r < 0) {
    + pm_runtime_put_autosuspend(adev->ddev->dev);
    return r;
    + }

    r = amdgpu_virt_enable_access_debugfs(adev);
    - if (r < 0)
    + if (r < 0) {
    + pm_runtime_put_autosuspend(adev->ddev->dev);
    return r;
    + }

    if (use_bank) {
    if ((sh_bank != 0xFFFFFFFF && sh_bank >= adev->gfx.config.max_sh_per_se) ||
    @@ -332,12 +336,16 @@ static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf,
    return -EINVAL;

    r = pm_runtime_get_sync(adev->ddev->dev);
    - if (r < 0)
    + if (r < 0) {
    + pm_runtime_put_autosuspend(adev->ddev->dev);
    return r;
    + }

    r = amdgpu_virt_enable_access_debugfs(adev);
    - if (r < 0)
    + if (r < 0) {
    + pm_runtime_put_autosuspend(adev->ddev->dev);
    return r;
    + }

    while (size) {
    uint32_t value;
    @@ -387,12 +395,16 @@ static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user
    return -EINVAL;

    r = pm_runtime_get_sync(adev->ddev->dev);
    - if (r < 0)
    + if (r < 0) {
    + pm_runtime_put_autosuspend(adev->ddev->dev);
    return r;
    + }

    r = amdgpu_virt_enable_access_debugfs(adev);
    - if (r < 0)
    + if (r < 0) {
    + pm_runtime_put_autosuspend(adev->ddev->dev);
    return r;
    + }

    while (size) {
    uint32_t value;
    @@ -443,12 +455,16 @@ static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf,
    return -EINVAL;

    r = pm_runtime_get_sync(adev->ddev->dev);
    - if (r < 0)
    + if (r < 0) {
    + pm_runtime_put_autosuspend(adev->ddev->dev);
    return r;
    + }

    r = amdgpu_virt_enable_access_debugfs(adev);
    - if (r < 0)
    + if (r < 0) {
    + pm_runtime_put_autosuspend(adev->ddev->dev);
    return r;
    + }

    while (size) {
    uint32_t value;
    @@ -498,12 +514,16 @@ static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user
    return -EINVAL;

    r = pm_runtime_get_sync(adev->ddev->dev);
    - if (r < 0)
    + if (r < 0) {
    + pm_runtime_put_autosuspend(adev->ddev->dev);
    return r;
    + }

    r = amdgpu_virt_enable_access_debugfs(adev);
    - if (r < 0)
    + if (r < 0) {
    + pm_runtime_put_autosuspend(adev->ddev->dev);
    return r;
    + }

    while (size) {
    uint32_t value;
    @@ -554,12 +574,16 @@ static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf,
    return -EINVAL;

    r = pm_runtime_get_sync(adev->ddev->dev);
    - if (r < 0)
    + if (r < 0) {
    + pm_runtime_put_autosuspend(adev->ddev->dev);
    return r;
    + }

    r = amdgpu_virt_enable_access_debugfs(adev);
    - if (r < 0)
    + if (r < 0) {
    + pm_runtime_put_autosuspend(adev->ddev->dev);
    return r;
    + }

    while (size) {
    uint32_t value;
    @@ -609,12 +633,16 @@ static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user *
    return -EINVAL;

    r = pm_runtime_get_sync(adev->ddev->dev);
    - if (r < 0)
    + if (r < 0) {
    + pm_runtime_put_autosuspend(adev->ddev->dev);
    return r;
    + }

    r = amdgpu_virt_enable_access_debugfs(adev);
    - if (r < 0)
    + if (r < 0) {
    + pm_runtime_put_autosuspend(adev->ddev->dev);
    return r;
    + }

    while (size) {
    uint32_t value;
    @@ -764,12 +792,16 @@ static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf,
    valuesize = sizeof(values);

    r = pm_runtime_get_sync(adev->ddev->dev);
    - if (r < 0)
    + if (r < 0) {
    + pm_runtime_put_autosuspend(adev->ddev->dev);
    return r;
    + }

    r = amdgpu_virt_enable_access_debugfs(adev);
    - if (r < 0)
    + if (r < 0) {
    + pm_runtime_put_autosuspend(adev->ddev->dev);
    return r;
    + }

    r = amdgpu_dpm_read_sensor(adev, idx, &values[0], &valuesize);

    @@ -842,12 +874,16 @@ static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf,
    simd = (*pos & GENMASK_ULL(44, 37)) >> 37;

    r = pm_runtime_get_sync(adev->ddev->dev);
    - if (r < 0)
    + if (r < 0) {
    + pm_runtime_put_autosuspend(adev->ddev->dev);
    return r;
    + }

    r = amdgpu_virt_enable_access_debugfs(adev);
    - if (r < 0)
    + if (r < 0) {
    + pm_runtime_put_autosuspend(adev->ddev->dev);
    return r;
    + }

    /* switch to the specific se/sh/cu */
    mutex_lock(&adev->grbm_idx_mutex);
    @@ -977,6 +1013,7 @@ static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf,
    }

    err:
    + pm_runtime_put_autosuspend(adev->ddev->dev);
    kfree(data);
    amdgpu_virt_disable_access_debugfs(adev);
    return result;
    @@ -1003,8 +1040,10 @@ static ssize_t amdgpu_debugfs_gfxoff_write(struct file *f, const char __user *bu
    return -EINVAL;

    r = pm_runtime_get_sync(adev->ddev->dev);
    - if (r < 0)
    + if (r < 0) {
    + pm_runtime_put_autosuspend(adev->ddev->dev);
    return r;
    + }

    while (size) {
    uint32_t value;
    @@ -1140,8 +1179,10 @@ static int amdgpu_debugfs_test_ib(struct seq_file *m, void *data)
    int r = 0, i;

    r = pm_runtime_get_sync(dev->dev);
    - if (r < 0)
    + if (r < 0) {
    + pm_runtime_put_autosuspend(adev->ddev->dev);
    return r;
    + }

    /* Avoid accidently unparking the sched thread during GPU reset */
    mutex_lock(&adev->lock_reset);
    @@ -1197,8 +1238,10 @@ static int amdgpu_debugfs_evict_vram(struct seq_file *m, void *data)
    int r;

    r = pm_runtime_get_sync(dev->dev);
    - if (r < 0)
    + if (r < 0) {
    + pm_runtime_put_autosuspend(adev->ddev->dev);
    return r;
    + }

    seq_printf(m, "(%d)\n", amdgpu_bo_evict_vram(adev));

    @@ -1216,8 +1259,10 @@ static int amdgpu_debugfs_evict_gtt(struct seq_file *m, void *data)
    int r;

    r = pm_runtime_get_sync(dev->dev);
    - if (r < 0)
    + if (r < 0) {
    + pm_runtime_put_autosuspend(adev->ddev->dev);
    return r;
    + }

    seq_printf(m, "(%d)\n", ttm_bo_evict_mm(&adev->mman.bdev, TTM_PL_TT));

    @@ -1417,16 +1462,16 @@ static int amdgpu_debugfs_sclk_set(void *data, u64 val)
    return -EINVAL;

    ret = pm_runtime_get_sync(adev->ddev->dev);
    - if (ret < 0)
    + if (ret < 0) {
    + pm_runtime_put_autosuspend(adev->ddev->dev);
    return ret;
    + }

    if (is_support_sw_smu(adev)) {
    ret = smu_get_dpm_freq_range(&adev->smu, SMU_SCLK, &min_freq, &max_freq, true);
    if (ret || val > max_freq || val < min_freq)
    return -EINVAL;
    ret = smu_set_soft_freq_range(&adev->smu, SMU_SCLK, (uint32_t)val, (uint32_t)val, true);
    - } else {
    - return 0;
    }

    pm_runtime_mark_last_busy(adev->ddev->dev);
    --
    2.25.1
    \
     
     \ /
      Last update: 2020-08-10 21:10    [W:4.511 / U:0.292 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site