From patchwork Tue May 7 09:36:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chunming Zhou X-Patchwork-Id: 10932687 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 2FF78912 for ; Tue, 7 May 2019 09:36:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1E22028929 for ; Tue, 7 May 2019 09:36:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 10BFA2893A; Tue, 7 May 2019 09:36:57 +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 484B128929 for ; Tue, 7 May 2019 09:36:56 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 3198189F89; Tue, 7 May 2019 09:36:53 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from NAM03-DM3-obe.outbound.protection.outlook.com (mail-eopbgr800089.outbound.protection.outlook.com [40.107.80.89]) by gabe.freedesktop.org (Postfix) with ESMTPS id 8E93989F89; Tue, 7 May 2019 09:36:51 +0000 (UTC) Received: from DM3PR12CA0084.namprd12.prod.outlook.com (2603:10b6:0:57::28) by CY4PR12MB1141.namprd12.prod.outlook.com (2603:10b6:903:44::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1856.14; Tue, 7 May 2019 09:36:49 +0000 Received: from BY2NAM03FT047.eop-NAM03.prod.protection.outlook.com (2a01:111:f400:7e4a::206) by DM3PR12CA0084.outlook.office365.com (2603:10b6:0:57::28) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.1856.10 via Frontend Transport; Tue, 7 May 2019 09:36:49 +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 BY2NAM03FT047.mail.protection.outlook.com (10.152.85.103) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.1856.11 via Frontend Transport; Tue, 7 May 2019 09:36:49 +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; Tue, 7 May 2019 04:36:47 -0500 From: Chunming Zhou To: , , , Subject: [PATCH 1/2] drm/ttm: fix busy memory to fail other user v6 Date: Tue, 7 May 2019 17:36:41 +0800 Message-ID: <20190507093642.7859-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)(39860400002)(346002)(376002)(136003)(396003)(2980300002)(428003)(199004)(189003)(72206003)(4326008)(2201001)(53416004)(316002)(14444005)(1076003)(50466002)(70206006)(70586007)(8676002)(126002)(486006)(81166006)(81156014)(476003)(16586007)(2616005)(426003)(86362001)(5660300002)(2906002)(77096007)(26005)(450100002)(48376002)(336012)(305945005)(186003)(110136005)(53936002)(47776003)(8936002)(68736007)(50226002)(356004)(36756003)(7696005)(51416003)(6666004)(478600001); DIR:OUT; SFP:1101; SCL:1; SRVR:CY4PR12MB1141; H:SATLEXCHOV02.amd.com; FPR:; SPF:None; LANG:en; PTR:InfoDomainNonexistent; A:1; MX:1; X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 3a390d7a-fe6f-4d77-33a8-08d6d2cf879a X-Microsoft-Antispam: BCL:0; PCL:0; RULEID:(2390118)(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600141)(711020)(4605104)(2017052603328); SRVR:CY4PR12MB1141; X-MS-TrafficTypeDiagnostic: CY4PR12MB1141: X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:8882; X-Forefront-PRVS: 0030839EEE X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam-Message-Info: LztLq4TLjT0P5pzedWBRny71dwmdeAFNFpPjnaw18AmbCMIQ811iW+oqYk1jv5+thLpWv5Xt9n0/pUVvKh79ruThbcFHjCEUzO2XoPcPMjc14IEzVBgH/NhX13jRRhMpgskTk7qDDQ/qM5iA9A4qsCj+a+9E5sF1+JRaMZZBFVG2i8NNAin2Ak0IopSMC+xrtHCP+ZFxPIK9aHOKaCmByAEm2/O2oNKDXLKo28BuWu2bM1OSCsJYElAQAmIpOVImXciiL6pdW5x15AU7Q+tLgaV45nYbl2wJ69LMPvKvB8qZJxR16rQjxMVAiba56uFLV5jOu/6ulTuAnnjNtmutcJ8zZ15uMHX+qZr95rhCBJoyO8lQo5oni62ICWueAO+eDoZPfHUsCN1VQT2fVn4IbLYc3dk8xPjg2dZQ856euBA= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 May 2019 09:36:49.2430 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 3a390d7a-fe6f-4d77-33a8-08d6d2cf879a 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: CY4PR12MB1141 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=n+5yQKUSZIMwy7J8v+tMxZmukesbLAvfcPr+FeeQykg=; b=Ll8YEcTvdUkWpXarkhL3aARbyLDt853t+nX1M68Hx62HEqF8fsMI3+82M3CtktiJQh4em2S3XAl7bwF6cyXP3m4/GRGQuom/8ETDK+hDbMcqFXmzkCYKY9DY7lpASI+wF8qZMcB9KCkMSXlpgr+fSLbzUDC4nEMy+1lr+5MR9zM= X-Mailman-Original-Authentication-Results: spf=none (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; lists.freedesktop.org; dkim=none (message not signed) header.d=none;lists.freedesktop.org; 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: , 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. v4: fix some missing v5: handle first_bo unlock and bo_get/put v6: abstract unified iterate function, and handle all possible usecase not only pinned bo. Change-Id: I21423fb922f885465f13833c41df1e134364a8e7 Signed-off-by: Chunming Zhou --- drivers/gpu/drm/ttm/ttm_bo.c | 113 ++++++++++++++++++++++++++++++----- 1 file changed, 97 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 8502b3ed2d88..bbf1d14d00a7 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -766,11 +766,13 @@ 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; + if (busy) + *busy = false; if (bo->resv == ctx->resv) { reservation_object_assert_held(bo->resv); if (ctx->flags & TTM_OPT_FLAG_ALLOW_RES_EVICT @@ -779,35 +781,45 @@ static bool ttm_bo_evict_swapout_allowable(struct ttm_buffer_object *bo, } else { *locked = reservation_object_trylock(bo->resv); ret = *locked; + if (!ret && busy) + *busy = true; } return ret; } -static int ttm_mem_evict_first(struct ttm_bo_device *bdev, - uint32_t mem_type, - const struct ttm_place *place, - struct ttm_operation_ctx *ctx) +static struct ttm_buffer_object* +ttm_mem_find_evitable_bo(struct ttm_bo_device *bdev, + struct ttm_mem_type_manager *man, + const struct ttm_place *place, + struct ttm_operation_ctx *ctx, + struct ttm_buffer_object **first_bo, + bool *locked) { - struct ttm_bo_global *glob = bdev->glob; - struct ttm_mem_type_manager *man = &bdev->man[mem_type]; struct ttm_buffer_object *bo = NULL; - bool locked = false; - unsigned i; - int ret; + int i; - spin_lock(&glob->lru_lock); + if (first_bo) + *first_bo = NULL; 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 && !(*first_bo) && busy) { + ttm_bo_get(bo); + *first_bo = bo; + } continue; + } if (place && !bdev->driver->eviction_valuable(bo, place)) { - if (locked) + if (*locked) reservation_object_unlock(bo->resv); continue; } + break; } @@ -818,9 +830,66 @@ static int ttm_mem_evict_first(struct ttm_bo_device *bdev, bo = NULL; } + return bo; +} + +static int ttm_mem_evict_first(struct ttm_bo_device *bdev, + uint32_t mem_type, + const struct ttm_place *place, + struct ttm_operation_ctx *ctx) +{ + struct ttm_bo_global *glob = bdev->glob; + struct ttm_mem_type_manager *man = &bdev->man[mem_type]; + struct ttm_buffer_object *bo = NULL, *first_bo = NULL; + bool locked = false; + int ret; + + spin_lock(&glob->lru_lock); + bo = ttm_mem_find_evitable_bo(bdev, man, place, ctx, &first_bo, + &locked); if (!bo) { + struct ttm_operation_ctx busy_ctx; + spin_unlock(&glob->lru_lock); - return -EBUSY; + /* check if other user occupy memory too long time */ + if (!first_bo || !ctx || !ctx->resv || !ctx->resv->lock.ctx) { + if (first_bo) + ttm_bo_put(first_bo); + return -EBUSY; + } + if (first_bo->resv == ctx->resv) { + ttm_bo_put(first_bo); + return -EBUSY; + } + if (ctx->interruptible) + ret = ww_mutex_lock_interruptible(&first_bo->resv->lock, + ctx->resv->lock.ctx); + else + ret = ww_mutex_lock(&first_bo->resv->lock, ctx->resv->lock.ctx); + if (ret) { + ttm_bo_put(first_bo); + return ret; + } + spin_lock(&glob->lru_lock); + /* previous busy resv lock is held by above, idle now, + * so let them evictable. + */ + busy_ctx.interruptible = ctx->interruptible; + busy_ctx.no_wait_gpu = ctx->no_wait_gpu; + busy_ctx.resv = first_bo->resv; + busy_ctx.flags = TTM_OPT_FLAG_ALLOW_RES_EVICT; + + bo = ttm_mem_find_evitable_bo(bdev, man, place, &busy_ctx, NULL, + &locked); + if (bo && (bo->resv == first_bo->resv)) + locked = true; + else if (bo) + ww_mutex_unlock(&first_bo->resv->lock); + if (!bo) { + spin_unlock(&glob->lru_lock); + ttm_bo_put(first_bo); + return -EBUSY; + } } kref_get(&bo->list_kref); @@ -829,11 +898,15 @@ static int ttm_mem_evict_first(struct ttm_bo_device *bdev, ret = ttm_bo_cleanup_refs(bo, ctx->interruptible, ctx->no_wait_gpu, locked); kref_put(&bo->list_kref, ttm_bo_release_list); + if (first_bo) + ttm_bo_put(first_bo); return ret; } ttm_bo_del_from_lru(bo); spin_unlock(&glob->lru_lock); + if (first_bo) + ttm_bo_put(first_bo); ret = ttm_bo_evict(bo, ctx); if (locked) { @@ -899,6 +972,13 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo, { struct ttm_bo_device *bdev = bo->bdev; struct ttm_mem_type_manager *man = &bdev->man[mem_type]; + struct ttm_operation_ctx native_ctx = { + .interruptible = false, + .no_wait_gpu = false, + .resv = bo->resv, + .flags = 0 + }; + struct ttm_operation_ctx *evict_ctx = ctx ? ctx : &native_ctx; int ret; do { @@ -907,7 +987,7 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo, return ret; if (mem->mm_node) break; - ret = ttm_mem_evict_first(bdev, mem_type, place, ctx); + ret = ttm_mem_evict_first(bdev, mem_type, place, evict_ctx); if (unlikely(ret != 0)) return ret; } while (1); @@ -1784,7 +1864,8 @@ 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)) { + if (ttm_bo_evict_swapout_allowable(bo, ctx, &locked, + NULL)) { ret = 0; break; }