From patchwork Thu Mar 13 02:05:15 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilia Mirkin X-Patchwork-Id: 3821591 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id EE3B89F2BB for ; Thu, 13 Mar 2014 02:05:31 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1317C2021F for ; Thu, 13 Mar 2014 02:05:31 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 022CB201BA for ; Thu, 13 Mar 2014 02:05:30 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9B66AFADA6; Wed, 12 Mar 2014 19:05:24 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-qa0-f43.google.com (mail-qa0-f43.google.com [209.85.216.43]) by gabe.freedesktop.org (Postfix) with ESMTP id DE24AFADA4; Wed, 12 Mar 2014 19:05:22 -0700 (PDT) Received: by mail-qa0-f43.google.com with SMTP id j15so387218qaq.2 for ; Wed, 12 Mar 2014 19:05:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id; bh=9IUV++BuCtGHucwR37+zRN1uLVipLkbAyht4kCckyAA=; b=uvO8OLFWjLxtTsOSp+pbwSvYvYyBHzScacc0fAucC6WtihuDzllR2ARQMDX27tr4LC L4OL+DdTB+AxOWcYCWtVQ2OgbYVN5wW9gKHPmEbk+KN2jU8zfM7qyww9tUAXG+ZWZ8aN TAXBmJSXI7CVUZXbJzSFXNfb+KNF1Ttgsd/RS47N4QhbatArUA2TsQUuK3Fao+10CZu9 vUkmw+QSkXp4IapEshDIzkvxUwLOlk280eJv2n4luQHCeqnV8reH2CTbTOztisF2m0pQ WqAyH5iMMbpi7eloLeQuYbxKbf2e+Bu3UDIxMrgLD3UXqLT/U+29CDPeNlFkKfcuooQl A1LQ== X-Received: by 10.224.22.147 with SMTP id n19mr9061qab.93.1394676322278; Wed, 12 Mar 2014 19:05:22 -0700 (PDT) Received: from localhost.localdomain (cpe-74-71-2-122.nyc.res.rr.com. [74.71.2.122]) by mx.google.com with ESMTPSA id t5sm1259856qge.0.2014.03.12.19.05.20 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 12 Mar 2014 19:05:21 -0700 (PDT) From: Ilia Mirkin To: nouveau@lists.freedesktop.org, dri-devel@lists.freedesktop.org, Ben Skeggs Subject: [PATCH] nouveau: safen up nouveau_device list usage against concurrent access Date: Wed, 12 Mar 2014 22:05:15 -0400 Message-Id: <1394676315-25595-1-git-send-email-imirkin@alum.mit.edu> X-Mailer: git-send-email 1.8.3.2 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dri-devel-bounces@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Ilia Mirkin Reviewed-by: Ben Skeggs --- nouveau/nouveau.c | 29 ++++++++++++++++++++++++++++- nouveau/private.h | 3 ++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c index ee7893b..72c31cf 100644 --- a/nouveau/nouveau.c +++ b/nouveau/nouveau.c @@ -85,6 +85,12 @@ nouveau_device_wrap(int fd, int close, struct nouveau_device **pdev) if (!nvdev) return -ENOMEM; + ret = pthread_mutex_init(&nvdev->lock, NULL); + if (ret) { + free(nvdev); + return ret; + } + nvdev->base.fd = fd; ver = drmGetVersion(fd); @@ -161,6 +167,7 @@ nouveau_device_del(struct nouveau_device **pdev) if (nvdev->close) drmClose(nvdev->base.fd); free(nvdev->client); + pthread_mutex_destroy(&nvdev->lock); free(nvdev); *pdev = NULL; } @@ -191,6 +198,8 @@ nouveau_client_new(struct nouveau_device *dev, struct nouveau_client **pclient) int id = 0, i, ret = -ENOMEM; uint32_t *clients; + pthread_mutex_lock(&nvdev->lock); + for (i = 0; i < nvdev->nr_client; i++) { id = ffs(nvdev->client[i]) - 1; if (id >= 0) @@ -199,7 +208,7 @@ nouveau_client_new(struct nouveau_device *dev, struct nouveau_client **pclient) clients = realloc(nvdev->client, sizeof(uint32_t) * (i + 1)); if (!clients) - return ret; + goto unlock; nvdev->client = clients; nvdev->client[i] = 0; nvdev->nr_client++; @@ -214,6 +223,9 @@ out: } *pclient = &pcli->base; + +unlock: + pthread_mutex_unlock(&nvdev->lock); return ret; } @@ -225,7 +237,9 @@ nouveau_client_del(struct nouveau_client **pclient) if (pcli) { int id = pcli->base.id; nvdev = nouveau_device(pcli->base.device); + pthread_mutex_lock(&nvdev->lock); nvdev->client[id / 32] &= ~(1 << (id % 32)); + pthread_mutex_unlock(&nvdev->lock); free(pcli->kref); free(pcli); } @@ -331,9 +345,12 @@ nouveau_object_find(struct nouveau_object *obj, uint32_t pclass) static void nouveau_bo_del(struct nouveau_bo *bo) { + struct nouveau_device_priv *nvdev = nouveau_device(bo->device); struct nouveau_bo_priv *nvbo = nouveau_bo(bo); struct drm_gem_close req = { bo->handle }; + pthread_mutex_lock(&nvdev->lock); DRMLISTDEL(&nvbo->head); + pthread_mutex_unlock(&nvdev->lock); if (bo->map) munmap(bo->map, bo->size); drmIoctl(bo->device->fd, DRM_IOCTL_GEM_CLOSE, &req); @@ -363,7 +380,9 @@ nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, uint32_t align, return ret; } + pthread_mutex_lock(&nvdev->lock); DRMLISTADD(&nvbo->head, &nvdev->bo_list); + pthread_mutex_unlock(&nvdev->lock); *pbo = bo; return 0; @@ -378,13 +397,16 @@ nouveau_bo_wrap(struct nouveau_device *dev, uint32_t handle, struct nouveau_bo_priv *nvbo; int ret; + pthread_mutex_lock(&nvdev->lock); DRMLISTFOREACHENTRY(nvbo, &nvdev->bo_list, head) { if (nvbo->base.handle == handle) { + pthread_mutex_unlock(&nvdev->lock); *pbo = NULL; nouveau_bo_ref(&nvbo->base, pbo); return 0; } } + pthread_mutex_unlock(&nvdev->lock); ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_GEM_INFO, &req, sizeof(req)); @@ -396,7 +418,9 @@ nouveau_bo_wrap(struct nouveau_device *dev, uint32_t handle, atomic_set(&nvbo->refcnt, 1); nvbo->base.device = dev; abi16_bo_info(&nvbo->base, &req); + pthread_mutex_lock(&nvdev->lock); DRMLISTADD(&nvbo->head, &nvdev->bo_list); + pthread_mutex_unlock(&nvdev->lock); *pbo = &nvbo->base; return 0; } @@ -413,13 +437,16 @@ nouveau_bo_name_ref(struct nouveau_device *dev, uint32_t name, struct drm_gem_open req = { .name = name }; int ret; + pthread_mutex_lock(&nvdev->lock); DRMLISTFOREACHENTRY(nvbo, &nvdev->bo_list, head) { if (nvbo->name == name) { + pthread_mutex_unlock(&nvdev->lock); *pbo = NULL; nouveau_bo_ref(&nvbo->base, pbo); return 0; } } + pthread_mutex_unlock(&nvdev->lock); ret = drmIoctl(dev->fd, DRM_IOCTL_GEM_OPEN, &req); if (ret == 0) { diff --git a/nouveau/private.h b/nouveau/private.h index 60714b8..4f337ad 100644 --- a/nouveau/private.h +++ b/nouveau/private.h @@ -3,6 +3,7 @@ #include #include +#include #include "nouveau_drm.h" #include "nouveau.h" @@ -94,7 +95,7 @@ nouveau_bo(struct nouveau_bo *bo) struct nouveau_device_priv { struct nouveau_device base; int close; - atomic_t lock; + pthread_mutex_t lock; struct nouveau_list bo_list; uint32_t *client; int nr_client;