From patchwork Thu Feb 21 18:42:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Matthew Wilcox (Oracle)" X-Patchwork-Id: 10825499 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 DD5FF1390 for ; Fri, 22 Feb 2019 08:22:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CC04D31B64 for ; Fri, 22 Feb 2019 08:22:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C02C631B45; Fri, 22 Feb 2019 08:22:14 +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 8E4F131B41 for ; Fri, 22 Feb 2019 08:22:09 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 12F8989450; Fri, 22 Feb 2019 08:21:29 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) by gabe.freedesktop.org (Postfix) with ESMTPS id 2B35289127 for ; Thu, 21 Feb 2019 18:42:37 +0000 (UTC) Received: from willy by bombadil.infradead.org with local (Exim 4.90_1 #2 (Red Hat Linux)) id 1gwtIq-0000hw-PJ; Thu, 21 Feb 2019 18:42:36 +0000 From: Matthew Wilcox To: dri-devel@lists.freedesktop.org Subject: [PATCH 27/34] drm/qxl: Convert surf_id_idr to XArray Date: Thu, 21 Feb 2019 10:42:12 -0800 Message-Id: <20190221184226.2149-53-willy@infradead.org> X-Mailer: git-send-email 2.14.5 In-Reply-To: <20190221184226.2149-1-willy@infradead.org> References: <20190221184226.2149-1-willy@infradead.org> X-Mailman-Approved-At: Fri, 22 Feb 2019 08:20:52 +0000 X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20170209; h=References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=Hk8SRs9vdjmCELONQqY15sxr7eYNIYO853qYCWajY+U=; b=cygfckbBJKOTIkqk1wWR2aBpl yfK4AIvtbuDShpVIkWSjJIlf/F1uGXMQptMu4CISbl93XaK+GLXCxEhAPHHzJDzsyHqLtWYhVY7Wx 7eD2u1UHwSw3inwJ33xt6ShMA1Smu3NCBJjGXycP1ZKqjeaE+uTKIQrlnFAv28pkS0gpgLk6DTRtu lG5CX7CiKCFEQkPVEkFMH7CnNPnCVwCMd4/ai+0mPXJW9/O540de4WNmneL5Y6teLbsSRDyfbwA3N wNBCnGaPSC9nEIfsSJHwMU8iPY8YP2YRCueVAtvOpjYVt/c7Vrq7lCo4JylgTeI3bmLprt/SF14Px XmgJPkxfw==; 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: Matthew Wilcox MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Matthew Wilcox --- drivers/gpu/drm/qxl/qxl_cmd.c | 60 ++++++++++++----------------------- drivers/gpu/drm/qxl/qxl_drv.h | 3 +- drivers/gpu/drm/qxl/qxl_kms.c | 5 +-- 3 files changed, 23 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_cmd.c b/drivers/gpu/drm/qxl/qxl_cmd.c index dffc5093ff16..afe8079453af 100644 --- a/drivers/gpu/drm/qxl/qxl_cmd.c +++ b/drivers/gpu/drm/qxl/qxl_cmd.c @@ -420,41 +420,27 @@ void qxl_io_monitors_config(struct qxl_device *qdev) int qxl_surface_id_alloc(struct qxl_device *qdev, struct qxl_bo *surf) { - uint32_t handle; - int idr_ret; - int count = 0; + int ret; again: - idr_preload(GFP_ATOMIC); - spin_lock(&qdev->surf_id_idr_lock); - idr_ret = idr_alloc(&qdev->surf_id_idr, NULL, 1, 0, GFP_NOWAIT); - spin_unlock(&qdev->surf_id_idr_lock); - idr_preload_end(); - if (idr_ret < 0) - return idr_ret; - handle = idr_ret; - - if (handle >= qdev->rom->n_surfaces) { - count++; - spin_lock(&qdev->surf_id_idr_lock); - idr_remove(&qdev->surf_id_idr, handle); - spin_unlock(&qdev->surf_id_idr_lock); + ret = xa_alloc(&qdev->surfaces, &surf->surface_id, NULL, + XA_LIMIT(0, qdev->rom->n_surfaces - 1), GFP_ATOMIC); + if (ret == -EBUSY) { qxl_reap_surface_id(qdev, 2); goto again; } - surf->surface_id = handle; + if (ret < 0) + return ret; - spin_lock(&qdev->surf_id_idr_lock); - qdev->last_alloced_surf_id = handle; - spin_unlock(&qdev->surf_id_idr_lock); + xa_lock(&qdev->surfaces); + qdev->last_alloced_surf_id = surf->surface_id; + xa_unlock(&qdev->surfaces); return 0; } void qxl_surface_id_dealloc(struct qxl_device *qdev, uint32_t surface_id) { - spin_lock(&qdev->surf_id_idr_lock); - idr_remove(&qdev->surf_id_idr, surface_id); - spin_unlock(&qdev->surf_id_idr_lock); + xa_erase(&qdev->surfaces, surface_id); } int qxl_hw_surface_alloc(struct qxl_device *qdev, @@ -507,9 +493,7 @@ int qxl_hw_surface_alloc(struct qxl_device *qdev, qxl_release_fence_buffer_objects(release); surf->hw_surf_alloc = true; - spin_lock(&qdev->surf_id_idr_lock); - idr_replace(&qdev->surf_id_idr, surf, surf->surface_id); - spin_unlock(&qdev->surf_id_idr_lock); + xa_store(&qdev->surfaces, surf->surface_id, surf, GFP_KERNEL); return 0; } @@ -531,10 +515,8 @@ int qxl_hw_surface_dealloc(struct qxl_device *qdev, return ret; surf->surf_create = NULL; - /* remove the surface from the idr, but not the surface id yet */ - spin_lock(&qdev->surf_id_idr_lock); - idr_replace(&qdev->surf_id_idr, NULL, surf->surface_id); - spin_unlock(&qdev->surf_id_idr_lock); + /* remove the surface from the array, but don't free the surface id */ + xa_store(&qdev->surfaces, surf->surface_id, NULL, 0); surf->hw_surf_alloc = false; id = surf->surface_id; @@ -623,20 +605,20 @@ static int qxl_reap_surface_id(struct qxl_device *qdev, int max_to_reap) mutex_lock(&qdev->surf_evict_mutex); again: - spin_lock(&qdev->surf_id_idr_lock); + xa_lock(&qdev->surfaces); start = qdev->last_alloced_surf_id + 1; - spin_unlock(&qdev->surf_id_idr_lock); + xa_unlock(&qdev->surfaces); for (i = start; i < start + qdev->rom->n_surfaces; i++) { void *objptr; int surfid = i % qdev->rom->n_surfaces; - /* this avoids the case where the objects is in the - idr but has been evicted half way - its makes - the idr lookup atomic with the eviction */ - spin_lock(&qdev->surf_id_idr_lock); - objptr = idr_find(&qdev->surf_id_idr, surfid); - spin_unlock(&qdev->surf_id_idr_lock); + /* this avoids the case where the object is in the + array but has been evicted half way - it makes + the array lookup atomic with the eviction */ + xa_lock(&qdev->surfaces); + objptr = xa_load(&qdev->surfaces, surfid); + xa_unlock(&qdev->surfaces); if (!objptr) continue; diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 3abd432a4b85..8d0254a133dc 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h @@ -260,8 +260,7 @@ struct qxl_device { struct mutex update_area_mutex; - struct idr surf_id_idr; - spinlock_t surf_id_idr_lock; + struct xarray surfaces; int last_alloced_surf_id; struct mutex surf_evict_mutex; diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c index b2cc71c95142..dafdb61f7a32 100644 --- a/drivers/gpu/drm/qxl/qxl_kms.c +++ b/drivers/gpu/drm/qxl/qxl_kms.c @@ -249,10 +249,7 @@ int qxl_device_init(struct qxl_device *qdev, xa_init_flags(&qdev->releases, XA_FLAGS_ALLOC1); spin_lock_init(&qdev->release_lock); - - idr_init(&qdev->surf_id_idr); - spin_lock_init(&qdev->surf_id_idr_lock); - + xa_init_flags(&qdev->surfaces, XA_FLAGS_ALLOC1); mutex_init(&qdev->async_io_mutex); /* reset the device into a known state - no memslots, no primary