Received: by 10.213.65.68 with SMTP id h4csp1408002imn; Thu, 29 Mar 2018 04:20:03 -0700 (PDT) X-Google-Smtp-Source: AIpwx49UZVNVRMP2oFmU4ghbqJC/3O60DtTt1BMjS6nzAMP/rfwhLOI4U8alYzN1EDgqv24a0tQ5 X-Received: by 10.98.223.149 with SMTP id d21mr6010720pfl.160.1522322403185; Thu, 29 Mar 2018 04:20:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1522322403; cv=none; d=google.com; s=arc-20160816; b=mRVXu90kVyTP3+1dr/mp/pOyYg8YalSmLGl9pgbuMkpe03REvF+vTtGk+jtxaSCSqP OiaU6s9BWLtxGj7Ipe+njjtDmdKuKhVvuagndpRgB8TOHCw6nnU1ej7ERwa7IXOmLCjL AVsBMFCVcF8HJu6+lxMBQrB/y/DXkWTo3gid2qT8PDd6YhQ2Q2G5xOA6asn5yF7Fbps2 x6IL07oUG1kILvvFd6Ez47t/PeDuRM4pY4N/cTP6igd8YGe5w8X6lpxI4LLXu9Sh6M1n FoiAunw3dCk0bLuOT757+WuYP+SZJ6QQGSx5iYm8R7Fl9gzJplBGgV2X6LTaZOJEummN lx6A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-language :content-transfer-encoding:in-reply-to:mime-version:user-agent:date :message-id:from:references:to:subject:dkim-signature :arc-authentication-results; bh=Q091KEgnH7JjgQCjBwwAS8JH8TUYR3KCP0A4aNbc2Us=; b=EcxnJ0/x2luAj7Jc2P0f1Vni6UyiCN+fXvx0DOJxnmRbgDQCNS/5eBOKqsZ77+03n6 ChGkQbqn/qvx+GNb57XxbCHMHHh+5Mt+D8ALgncPIkb16ACVGgNjE6STPl1kr6AO564M LkYtgd3C2pGaWRJxVjClBsi7SXQVW2XSlKnXOaNLi9dI4F2Y95cdWHnoejb9ltlPuIx8 zmHNviJF/ardLB2Mk7aK9rWbwemAox6LZSWofstqaMrHaGFscdOeiOUo6uLEJqC+XfoR M6/ZRUoGQTm3m8N19xIWfNzkte5eQ0yPO5UphnpQZXseXKJgOcsdE3QxFvXKCeDUsnPn QrhA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=hFOHiFJJ; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id k8si3912568pgs.555.2018.03.29.04.19.48; Thu, 29 Mar 2018 04:20:03 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=hFOHiFJJ; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752319AbeC2LSt (ORCPT + 99 others); Thu, 29 Mar 2018 07:18:49 -0400 Received: from mail-lf0-f67.google.com ([209.85.215.67]:37163 "EHLO mail-lf0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751897AbeC2LSr (ORCPT ); Thu, 29 Mar 2018 07:18:47 -0400 Received: by mail-lf0-f67.google.com with SMTP id m200-v6so2117422lfm.4 for ; Thu, 29 Mar 2018 04:18:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-transfer-encoding:content-language; bh=Q091KEgnH7JjgQCjBwwAS8JH8TUYR3KCP0A4aNbc2Us=; b=hFOHiFJJiOfxpN9BjeC5/TZPSGCDuI/YFO4ZO5nVecm2dJEw1B+o3Db5VNClSVX8Xc altIMzLGVfxPJJctsyDNmeuk7RxYq/MxTKinqHTIoEZBSP3BwGq38QiBXO4gx4F7MS4O STPSpqY8lT6BunFnNCDgGQJlzRpZgl/kPqqYfnPvEclj5aOYS1PgsOvNqpv7rhHCrhR4 GbVWt6ySWx6EHkflHeUUS2tFo4Ak5/NT11OAppcgZHnHJkuUX1jr/mfe7U2/ZXZ8Q/M4 ti6OsBUlKkHyYMzGGXrFt13BaKUJX57leGd8ybbgWAB32FNTyU4LpqwfbIu11o6VmbQB 2Qbg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-transfer-encoding :content-language; bh=Q091KEgnH7JjgQCjBwwAS8JH8TUYR3KCP0A4aNbc2Us=; b=jEHf4JMqr9yr1NDGdC+Ae7uWgTQz86JpYGS9OgVGPXfq98a4EkoIE5nZib0MheV1qi nOaacbNRq6Wvp6Bxsp0z92Z1pc5qAg/n3ZmM5S5UgtQmBpe8QkYbWBUM5KiWOC0NRzu/ efq9Tskz3kDTX8CBH2b0FARRpBmg5ipR7DYc4kxmjSKoaenvlDZm353A/sIfPJPociBr Ty21uD5JBO/cvZTfL52PqXTOkMSfma4kwRSJYtp7T3F+lNyiRf0Yd0Hyucy6aW0NtOK/ 0uSlDH9gKqHHVdSt40rQk+0Ce5SSCsOSEtkOdZHEbu//XpT+srtgABjN88bEJ3UjxgOu WFog== X-Gm-Message-State: AElRT7H0pgn5bF8Y5kZqC8YnSZilGudPhGpjgCc+LXtkqk8iSonCwL2v K2l/G6JrAqOb89G6NJ0au08= X-Received: by 10.46.32.154 with SMTP id g26mr5108693lji.71.1522322325998; Thu, 29 Mar 2018 04:18:45 -0700 (PDT) Received: from [10.17.182.9] (ll-59.209.223.85.sovam.net.ua. [85.223.209.59]) by smtp.gmail.com with ESMTPSA id n83sm227484lja.31.2018.03.29.04.18.44 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 29 Mar 2018 04:18:45 -0700 (PDT) Subject: Re: [PATCH] drm: Use srcu to protect drm_device.unplugged To: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, airlied@linux.ie, daniel.vetter@intel.com, seanpaul@chromium.org, gustavo@padovan.org, intel-gfx@lists.freedesktop.org, Oleksandr Andrushchenko References: <1522222715-11814-1-git-send-email-andr2000@gmail.com> <20180328150926.GC3881@phenom.ffwll.local> From: Oleksandr Andrushchenko Message-ID: <804f94d8-9f21-159b-220e-ca420a83c176@gmail.com> Date: Thu, 29 Mar 2018 14:18:44 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0 MIME-Version: 1.0 In-Reply-To: <20180328150926.GC3881@phenom.ffwll.local> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-US Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 03/28/2018 06:09 PM, Daniel Vetter wrote: > On Wed, Mar 28, 2018 at 10:38:35AM +0300, Oleksandr Andrushchenko wrote: >> From: Noralf Trønnes >> >> Use srcu to protect drm_device.unplugged in a race free manner. >> Drivers can use drm_dev_enter()/drm_dev_exit() to protect and mark >> sections preventing access to device resources that are not available >> after the device is gone. >> >> Suggested-by: Daniel Vetter >> Signed-off-by: Noralf Trønnes >> Signed-off-by: Oleksandr Andrushchenko >> Reviewed-by: Oleksandr Andrushchenko >> Tested-by: Oleksandr Andrushchenko >> Cc: intel-gfx@lists.freedesktop.org > Reviewed-by: Daniel Vetter > > Oleksandr, please push to drm-misc-next once you have dim tools setup up > and everything. Pushed to drm-misc-next > > Thanks, Daniel Thank you, Oleksandr >> --- >> drivers/gpu/drm/drm_drv.c | 54 ++++++++++++++++++++++++++++++++++++++++++----- >> include/drm/drm_device.h | 9 +++++++- >> include/drm/drm_drv.h | 15 +++++++++---- >> 3 files changed, 68 insertions(+), 10 deletions(-) >> >> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c >> index a1b9338736e3..32a83b41ab61 100644 >> --- a/drivers/gpu/drm/drm_drv.c >> +++ b/drivers/gpu/drm/drm_drv.c >> @@ -32,6 +32,7 @@ >> #include >> #include >> #include >> +#include >> >> #include >> #include >> @@ -75,6 +76,8 @@ static bool drm_core_init_complete = false; >> >> static struct dentry *drm_debugfs_root; >> >> +DEFINE_STATIC_SRCU(drm_unplug_srcu); >> + >> /* >> * DRM Minors >> * A DRM device can provide several char-dev interfaces on the DRM-Major. Each >> @@ -318,18 +321,51 @@ void drm_put_dev(struct drm_device *dev) >> } >> EXPORT_SYMBOL(drm_put_dev); >> >> -static void drm_device_set_unplugged(struct drm_device *dev) >> +/** >> + * drm_dev_enter - Enter device critical section >> + * @dev: DRM device >> + * @idx: Pointer to index that will be passed to the matching drm_dev_exit() >> + * >> + * This function marks and protects the beginning of a section that should not >> + * be entered after the device has been unplugged. The section end is marked >> + * with drm_dev_exit(). Calls to this function can be nested. >> + * >> + * Returns: >> + * True if it is OK to enter the section, false otherwise. >> + */ >> +bool drm_dev_enter(struct drm_device *dev, int *idx) >> +{ >> + *idx = srcu_read_lock(&drm_unplug_srcu); >> + >> + if (dev->unplugged) { >> + srcu_read_unlock(&drm_unplug_srcu, *idx); >> + return false; >> + } >> + >> + return true; >> +} >> +EXPORT_SYMBOL(drm_dev_enter); >> + >> +/** >> + * drm_dev_exit - Exit device critical section >> + * @idx: index returned from drm_dev_enter() >> + * >> + * This function marks the end of a section that should not be entered after >> + * the device has been unplugged. >> + */ >> +void drm_dev_exit(int idx) >> { >> - smp_wmb(); >> - atomic_set(&dev->unplugged, 1); >> + srcu_read_unlock(&drm_unplug_srcu, idx); >> } >> +EXPORT_SYMBOL(drm_dev_exit); >> >> /** >> * drm_dev_unplug - unplug a DRM device >> * @dev: DRM device >> * >> * This unplugs a hotpluggable DRM device, which makes it inaccessible to >> - * userspace operations. Entry-points can use drm_dev_is_unplugged(). This >> + * userspace operations. Entry-points can use drm_dev_enter() and >> + * drm_dev_exit() to protect device resources in a race free manner. This >> * essentially unregisters the device like drm_dev_unregister(), but can be >> * called while there are still open users of @dev. >> */ >> @@ -338,10 +374,18 @@ void drm_dev_unplug(struct drm_device *dev) >> drm_dev_unregister(dev); >> >> mutex_lock(&drm_global_mutex); >> - drm_device_set_unplugged(dev); >> if (dev->open_count == 0) >> drm_dev_put(dev); >> mutex_unlock(&drm_global_mutex); >> + >> + /* >> + * After synchronizing any critical read section is guaranteed to see >> + * the new value of ->unplugged, and any critical section which might >> + * still have seen the old value of ->unplugged is guaranteed to have >> + * finished. >> + */ >> + dev->unplugged = true; >> + synchronize_srcu(&drm_unplug_srcu); >> } >> EXPORT_SYMBOL(drm_dev_unplug); >> >> diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h >> index 7c4fa32f3fc6..3a0eac2885b7 100644 >> --- a/include/drm/drm_device.h >> +++ b/include/drm/drm_device.h >> @@ -46,7 +46,14 @@ struct drm_device { >> /* currently active master for this device. Protected by master_mutex */ >> struct drm_master *master; >> >> - atomic_t unplugged; /**< Flag whether dev is dead */ >> + /** >> + * @unplugged: >> + * >> + * Flag to tell if the device has been unplugged. >> + * See drm_dev_enter() and drm_dev_is_unplugged(). >> + */ >> + bool unplugged; >> + >> struct inode *anon_inode; /**< inode for private address-space */ >> char *unique; /**< unique name of the device */ >> /*@} */ >> diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h >> index d23dcdd1bd95..7e545f5f94d3 100644 >> --- a/include/drm/drm_drv.h >> +++ b/include/drm/drm_drv.h >> @@ -624,6 +624,8 @@ void drm_dev_get(struct drm_device *dev); >> void drm_dev_put(struct drm_device *dev); >> void drm_dev_unref(struct drm_device *dev); >> void drm_put_dev(struct drm_device *dev); >> +bool drm_dev_enter(struct drm_device *dev, int *idx); >> +void drm_dev_exit(int idx); >> void drm_dev_unplug(struct drm_device *dev); >> >> /** >> @@ -635,11 +637,16 @@ void drm_dev_unplug(struct drm_device *dev); >> * unplugged, these two functions guarantee that any store before calling >> * drm_dev_unplug() is visible to callers of this function after it completes >> */ >> -static inline int drm_dev_is_unplugged(struct drm_device *dev) >> +static inline bool drm_dev_is_unplugged(struct drm_device *dev) >> { >> - int ret = atomic_read(&dev->unplugged); >> - smp_rmb(); >> - return ret; >> + int idx; >> + >> + if (drm_dev_enter(dev, &idx)) { >> + drm_dev_exit(idx); >> + return false; >> + } >> + >> + return true; >> } >> >> >> -- >> 2.7.4 >> >> _______________________________________________ >> dri-devel mailing list >> dri-devel@lists.freedesktop.org >> https://lists.freedesktop.org/mailman/listinfo/dri-devel