lkml.org 
[lkml]   [2022]   [Jul]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.15 076/167] drm/i915/gt: Serialize GRDOM access between multiple engine resets
    Date
    From: Chris Wilson <chris@chris-wilson.co.uk>

    [ Upstream commit b24dcf1dc507f69ed3b5c66c2b6a0209ae80d4d4 ]

    Don't allow two engines to be reset in parallel, as they would both
    try to select a reset bit (and send requests to common registers)
    and wait on that register, at the same time. Serialize control of
    the reset requests/acks using the uncore->lock, which will also ensure
    that no other GT state changes at the same time as the actual reset.

    Cc: stable@vger.kernel.org # v4.4 and upper
    Reported-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
    Acked-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
    Reviewed-by: Andi Shyti <andi.shyti@intel.com>
    Reviewed-by: Andrzej Hajda <andrzej.hajda@intel.com>
    Acked-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
    Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
    Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/e0a2d894e77aed7c2e36b0d1abdc7dbac3011729.1657639152.git.mchehab@kernel.org
    (cherry picked from commit 336561a914fc0c6f1218228718f633b31b7af1c3)
    Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/gpu/drm/i915/gt/intel_reset.c | 37 ++++++++++++++++++++-------
    1 file changed, 28 insertions(+), 9 deletions(-)

    diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c b/drivers/gpu/drm/i915/gt/intel_reset.c
    index b6697c1d260a..18b0e57c58c1 100644
    --- a/drivers/gpu/drm/i915/gt/intel_reset.c
    +++ b/drivers/gpu/drm/i915/gt/intel_reset.c
    @@ -293,9 +293,9 @@ static int gen6_hw_domain_reset(struct intel_gt *gt, u32 hw_domain_mask)
    return err;
    }

    -static int gen6_reset_engines(struct intel_gt *gt,
    - intel_engine_mask_t engine_mask,
    - unsigned int retry)
    +static int __gen6_reset_engines(struct intel_gt *gt,
    + intel_engine_mask_t engine_mask,
    + unsigned int retry)
    {
    static const u32 hw_engine_mask[] = {
    [RCS0] = GEN6_GRDOM_RENDER,
    @@ -322,6 +322,20 @@ static int gen6_reset_engines(struct intel_gt *gt,
    return gen6_hw_domain_reset(gt, hw_mask);
    }

    +static int gen6_reset_engines(struct intel_gt *gt,
    + intel_engine_mask_t engine_mask,
    + unsigned int retry)
    +{
    + unsigned long flags;
    + int ret;
    +
    + spin_lock_irqsave(&gt->uncore->lock, flags);
    + ret = __gen6_reset_engines(gt, engine_mask, retry);
    + spin_unlock_irqrestore(&gt->uncore->lock, flags);
    +
    + return ret;
    +}
    +
    static struct intel_engine_cs *find_sfc_paired_vecs_engine(struct intel_engine_cs *engine)
    {
    int vecs_id;
    @@ -488,9 +502,9 @@ static void gen11_unlock_sfc(struct intel_engine_cs *engine)
    rmw_clear_fw(uncore, sfc_lock.lock_reg, sfc_lock.lock_bit);
    }

    -static int gen11_reset_engines(struct intel_gt *gt,
    - intel_engine_mask_t engine_mask,
    - unsigned int retry)
    +static int __gen11_reset_engines(struct intel_gt *gt,
    + intel_engine_mask_t engine_mask,
    + unsigned int retry)
    {
    static const u32 hw_engine_mask[] = {
    [RCS0] = GEN11_GRDOM_RENDER,
    @@ -601,8 +615,11 @@ static int gen8_reset_engines(struct intel_gt *gt,
    struct intel_engine_cs *engine;
    const bool reset_non_ready = retry >= 1;
    intel_engine_mask_t tmp;
    + unsigned long flags;
    int ret;

    + spin_lock_irqsave(&gt->uncore->lock, flags);
    +
    for_each_engine_masked(engine, gt, engine_mask, tmp) {
    ret = gen8_engine_reset_prepare(engine);
    if (ret && !reset_non_ready)
    @@ -630,17 +647,19 @@ static int gen8_reset_engines(struct intel_gt *gt,
    * This is best effort, so ignore any error from the initial reset.
    */
    if (IS_DG2(gt->i915) && engine_mask == ALL_ENGINES)
    - gen11_reset_engines(gt, gt->info.engine_mask, 0);
    + __gen11_reset_engines(gt, gt->info.engine_mask, 0);

    if (GRAPHICS_VER(gt->i915) >= 11)
    - ret = gen11_reset_engines(gt, engine_mask, retry);
    + ret = __gen11_reset_engines(gt, engine_mask, retry);
    else
    - ret = gen6_reset_engines(gt, engine_mask, retry);
    + ret = __gen6_reset_engines(gt, engine_mask, retry);

    skip_reset:
    for_each_engine_masked(engine, gt, engine_mask, tmp)
    gen8_engine_reset_cancel(engine);

    + spin_unlock_irqrestore(&gt->uncore->lock, flags);
    +
    return ret;
    }

    --
    2.35.1


    \
     
     \ /
      Last update: 2022-07-19 14:38    [W:4.200 / U:0.028 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site