From patchwork Thu Apr 25 07:39:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chunming Zhou X-Patchwork-Id: 10916187 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4ADB0161F for ; Thu, 25 Apr 2019 07:39:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3C42828BA6 for ; Thu, 25 Apr 2019 07:39:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2E49428BDE; Thu, 25 Apr 2019 07:39:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 5E45128BD7 for ; Thu, 25 Apr 2019 07:39:39 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 3211F89272; Thu, 25 Apr 2019 07:39:37 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from NAM03-BY2-obe.outbound.protection.outlook.com (mail-eopbgr780071.outbound.protection.outlook.com [40.107.78.71]) by gabe.freedesktop.org (Postfix) with ESMTPS id 673A289272 for ; Thu, 25 Apr 2019 07:39:36 +0000 (UTC) Received: from MWHPR1201CA0012.namprd12.prod.outlook.com (2603:10b6:301:4a::22) by DM6PR12MB3468.namprd12.prod.outlook.com (2603:10b6:5:3c::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1835.12; Thu, 25 Apr 2019 07:39:35 +0000 Received: from DM3NAM03FT020.eop-NAM03.prod.protection.outlook.com (2a01:111:f400:7e49::206) by MWHPR1201CA0012.outlook.office365.com (2603:10b6:301:4a::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1835.12 via Frontend Transport; Thu, 25 Apr 2019 07:39:34 +0000 Received-SPF: None (protection.outlook.com: amd.com does not designate permitted sender hosts) Received: from SATLEXCHOV02.amd.com (165.204.84.17) by DM3NAM03FT020.mail.protection.outlook.com (10.152.82.193) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.1792.25 via Frontend Transport; Thu, 25 Apr 2019 07:39:34 +0000 Received: from zhoucm1.amd.com (10.34.1.3) by SATLEXCHOV02.amd.com (10.181.40.72) with Microsoft SMTP Server id 14.3.389.1; Thu, 25 Apr 2019 02:39:32 -0500 From: Chunming Zhou To: Subject: [PATCH] drm/ttm: fix busy memory to fail other user v3 Date: Thu, 25 Apr 2019 15:39:26 +0800 Message-ID: <20190425073926.30689-1-david1.zhou@amd.com> X-Mailer: git-send-email 2.17.1 MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-HT: Tenant X-Forefront-Antispam-Report: CIP:165.204.84.17; IPV:NLI; CTRY:US; EFV:NLI; SFV:NSPM; SFS:(10009020)(136003)(39860400002)(376002)(346002)(396003)(2980300002)(428003)(189003)(199004)(50226002)(26005)(97736004)(2906002)(126002)(486006)(476003)(426003)(6666004)(1076003)(81166006)(86362001)(48376002)(2616005)(14444005)(81156014)(8676002)(50466002)(356004)(77096007)(36756003)(8936002)(68736007)(7696005)(186003)(51416003)(336012)(54906003)(5660300002)(53416004)(47776003)(305945005)(53936002)(2351001)(72206003)(70586007)(316002)(478600001)(16586007)(70206006)(6916009)(4326008); DIR:OUT; SFP:1101; SCL:1; SRVR:DM6PR12MB3468; H:SATLEXCHOV02.amd.com; FPR:; SPF:None; LANG:en; PTR:InfoDomainNonexistent; MX:1; A:1; X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 8155ee4a-28a0-4762-c524-08d6c9512966 X-Microsoft-Antispam: BCL:0; PCL:0; RULEID:(2390118)(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600141)(711020)(4605104)(2017052603328); SRVR:DM6PR12MB3468; X-MS-TrafficTypeDiagnostic: DM6PR12MB3468: X-Microsoft-Antispam-PRVS: X-Forefront-PRVS: 0018A2705B X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam-Message-Info: ZGxbvaC06DsUW5MU15/BG84R3NizAI8F3zlNbcHnyd1gflSgiQrKw6sBB4bwxY4OsZvhg6DjxTz5WERfjPkMxocK+ePfnxEafbGBfNkenazqQ6B6O3dmH/NQLWa/b3xCZeZz0Cwjvz/a3IG1y/v0xZUJcPsj9qHvxOJFQqPt1qPKAZUR3sUutAj+M5mTYwXdjxJgAvJbev/5vIWzRODvNBxVcBm5cjs/TennRfQxkDQySY+p4cBa1xAYn+Ah2MXhmCWp75xkT8pgKgFRM1rYFbO8ezeugPt3ipVxg4Zxuy4BTgbsMgr66TyKTgFTE1+CsillkuVs9Fr1Gwk9B5MUjVkQZlx5Be460tQ2FCXbWENvrWNMKORpK0/gUAlu33j1d+Jqj7+PHhKMUk5YCUjYn3uvHuU3GDyXzc0HJsXpC38= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 25 Apr 2019 07:39:34.1652 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 8155ee4a-28a0-4762-c524-08d6c9512966 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d; Ip=[165.204.84.17]; Helo=[SATLEXCHOV02.amd.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB3468 X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amdcloud.onmicrosoft.com; s=selector1-amd-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Wpzo0DceBh/korHG1d7zyHyz4rom6xqeHZ1BAKbz1CY=; b=pswx61gD/lMFNTDe89iqrb8fcKZexuJntIbXCmfwZGa0a45ha4IqJyOGjbleU8FYe2OSc+fku6CDXvEogPeCVoGSOWgX8ebiIDPc3r3temwAaCLlR8y1Iz0kHUDTywA886zCk0D13yTgFUwML+RIISsS83VLgyMRqSmX4v4O1Vg= X-Mailman-Original-Authentication-Results: spf=none (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; gmail.com; dkim=none (message not signed) header.d=none;gmail.com; dmarc=permerror action=none header.from=amd.com; X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ckoenig.leichtzumerken@gmail.com, prike.liang@amd.com Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP heavy gpu job could occupy memory long time, which lead other user fail to get memory. basically pick up Christian idea: 1. Reserve the BO in DC using a ww_mutex ticket (trivial). 2. If we then run into this EBUSY condition in TTM check if the BO we need memory for (or rather the ww_mutex of its reservation object) has a ticket assigned. 3. If we have a ticket we grab a reference to the first BO on the LRU, drop the LRU lock and try to grab the reservation lock with the ticket. 4. If getting the reservation lock with the ticket succeeded we check if the BO is still the first one on the LRU in question (the BO could have moved). 5. If the BO is still the first one on the LRU in question we try to evict it as we would evict any other BO. 6. If any of the "If's" above fail we just back off and return -EBUSY. v2: fix some minor check v3: address Christian v2 comments. Change-Id: I21423fb922f885465f13833c41df1e134364a8e7 Signed-off-by: Chunming Zhou --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 7 ++- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 21 ++++++-- drivers/gpu/drm/ttm/ttm_bo.c | 48 +++++++++++++++++-- 3 files changed, 67 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index affde72b44db..015bf62277d0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -811,7 +811,12 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, u64 min_offset, u64 max_offset) { struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); - struct ttm_operation_ctx ctx = { false, false }; + struct ttm_operation_ctx ctx = { + .interruptible = false, + .no_wait_gpu = false, + .resv = bo->tbo.resv, + .flags = TTM_OPT_FLAG_ALLOW_RES_EVICT + }; int r, i; if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm)) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index a5cacf846e1b..2957ac38dcb0 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4101,6 +4101,9 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane, struct amdgpu_device *adev; struct amdgpu_bo *rbo; struct dm_plane_state *dm_plane_state_new, *dm_plane_state_old; + struct list_head list, duplicates; + struct ttm_validate_buffer tv; + struct ww_acquire_ctx ticket; uint64_t tiling_flags; uint32_t domain; int r; @@ -4120,6 +4123,18 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane, r = amdgpu_bo_reserve(rbo, false); if (unlikely(r != 0)) return r; + INIT_LIST_HEAD(&list); + INIT_LIST_HEAD(&duplicates); + + tv.bo = &rbo->tbo; + tv.num_shared = 1; + list_add(&tv.head, &list); + + r = ttm_eu_reserve_buffers(&ticket, &list, false, &duplicates); + if (r) { + dev_err(adev->dev, "fail to reserve bo (%d)\n", r); + return r; + } if (plane->type != DRM_PLANE_TYPE_CURSOR) domain = amdgpu_display_supported_domains(adev); @@ -4130,21 +4145,21 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane, if (unlikely(r != 0)) { if (r != -ERESTARTSYS) DRM_ERROR("Failed to pin framebuffer with error %d\n", r); - amdgpu_bo_unreserve(rbo); + ttm_eu_backoff_reservation(&ticket, &list); return r; } r = amdgpu_ttm_alloc_gart(&rbo->tbo); if (unlikely(r != 0)) { amdgpu_bo_unpin(rbo); - amdgpu_bo_unreserve(rbo); + ttm_eu_backoff_reservation(&ticket, &list); DRM_ERROR("%p bind failed\n", rbo); return r; } amdgpu_bo_get_tiling_flags(rbo, &tiling_flags); - amdgpu_bo_unreserve(rbo); + ttm_eu_backoff_reservation(&ticket, &list); afb->address = amdgpu_bo_gpu_offset(rbo); diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 8502b3ed2d88..dbcf958d1b43 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -766,11 +766,12 @@ EXPORT_SYMBOL(ttm_bo_eviction_valuable); * b. Otherwise, trylock it. */ static bool ttm_bo_evict_swapout_allowable(struct ttm_buffer_object *bo, - struct ttm_operation_ctx *ctx, bool *locked) + struct ttm_operation_ctx *ctx, bool *locked, bool *busy) { bool ret = false; *locked = false; + *busy = false; if (bo->resv == ctx->resv) { reservation_object_assert_held(bo->resv); if (ctx->flags & TTM_OPT_FLAG_ALLOW_RES_EVICT @@ -779,6 +780,8 @@ static bool ttm_bo_evict_swapout_allowable(struct ttm_buffer_object *bo, } else { *locked = reservation_object_trylock(bo->resv); ret = *locked; + if (!ret) + *busy = true; } return ret; @@ -791,7 +794,7 @@ static int ttm_mem_evict_first(struct ttm_bo_device *bdev, { struct ttm_bo_global *glob = bdev->glob; struct ttm_mem_type_manager *man = &bdev->man[mem_type]; - struct ttm_buffer_object *bo = NULL; + struct ttm_buffer_object *bo = NULL, *first_bo = NULL; bool locked = false; unsigned i; int ret; @@ -799,8 +802,13 @@ static int ttm_mem_evict_first(struct ttm_bo_device *bdev, spin_lock(&glob->lru_lock); for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) { list_for_each_entry(bo, &man->lru[i], lru) { - if (!ttm_bo_evict_swapout_allowable(bo, ctx, &locked)) + bool busy = false; + if (!ttm_bo_evict_swapout_allowable(bo, ctx, &locked, + &busy)) { + if (!first_bo && busy) + first_bo = bo; continue; + } if (place && !bdev->driver->eviction_valuable(bo, place)) { @@ -808,6 +816,7 @@ static int ttm_mem_evict_first(struct ttm_bo_device *bdev, reservation_object_unlock(bo->resv); continue; } + break; } @@ -820,7 +829,33 @@ static int ttm_mem_evict_first(struct ttm_bo_device *bdev, if (!bo) { spin_unlock(&glob->lru_lock); - return -EBUSY; + if (!first_bo || !ctx || !ctx->resv || !ctx->resv->lock.ctx) + return -EBUSY; + if (ctx->interruptible) + ret = ww_mutex_lock_interruptible(&bo->resv->lock, + ctx->resv->lock.ctx); + else + ret = ww_mutex_lock(&bo->resv->lock, ctx->resv->lock.ctx); + if (ret) + return ret; + spin_lock(&glob->lru_lock); + for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) { + if (list_empty(&man->lru[i])) + continue; + bo = list_first_entry(&man->lru[i], + struct ttm_buffer_object, + lru); + + break; + } + /* verify if BO have been moved */ + if (first_bo != bo) { + spin_unlock(&glob->lru_lock); + ww_mutex_unlock(&bo->resv->lock); + return -EBUSY; + } + spin_unlock(&glob->lru_lock); + /* ok, pick up first busy BO to wait to evict */ } kref_get(&bo->list_kref); @@ -1784,7 +1819,10 @@ int ttm_bo_swapout(struct ttm_bo_global *glob, struct ttm_operation_ctx *ctx) spin_lock(&glob->lru_lock); for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) { list_for_each_entry(bo, &glob->swap_lru[i], swap) { - if (ttm_bo_evict_swapout_allowable(bo, ctx, &locked)) { + bool busy = false; + + if (ttm_bo_evict_swapout_allowable(bo, ctx, &locked, + &busy)) { ret = 0; break; }