Received: by 2002:a05:6a10:413:0:0:0:0 with SMTP id 19csp3592949pxp; Tue, 8 Mar 2022 18:19:11 -0800 (PST) X-Google-Smtp-Source: ABdhPJyjPw9Ix6UHrA8Ym2ZNZIoQI+43QCS3ANu3AnW65PqPieyaq0AjbebKDIfH6lUdX4OfmK3X X-Received: by 2002:a17:90b:1941:b0:1bf:5440:d716 with SMTP id nk1-20020a17090b194100b001bf5440d716mr7875357pjb.147.1646792350961; Tue, 08 Mar 2022 18:19:10 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1646792350; cv=none; d=google.com; s=arc-20160816; b=a2RocKMKAk5Az2JaQgbepEVDZH3Ar9zyg8Q1X5kGsi7aKZoHdQb1ORfp4ITxHUKSx0 sTMoi/xZmVfUttu26hyoX9HJTTUFvxPp8cWD7SfBMymCC+gnR4MjE15OIE5wcC7apgeB 2R+yghqddGlLpRo/Fc7OGPgXJu4KfNGe79QRa7Ka6xJ+OQl6E3tlqGOa9bAf9PFPzDeJ WuLT3L6UTrq90+clenkRVDwHD2FHx+wkpsJQvnQGpctoRJoio+AVlc2ni//8BU8POJ6Q E5gCfZb7VpaTO0gh7Pmd1+5quh/jBwdQNtyyocVK2zBBuxYQWEiIjCYCXp8N8Z3ObOxm 7zeQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:dkim-signature; bh=jpY2z4H34H3eyBeRRD+CGY7silW4WSqrGPqcmBECpU8=; b=cfGAC3iGAsz9ERzaD0lmcOoa2egNPQSUiZj4t/D0iWc0DVh29YFJLkzqYBY+insnW7 jaEzp6s/NujH3i+GlZugktQADrtaWRZyL3i6tClR3Zvh92qoYMNTiSjoJbS5XxKEFTa+ rmLkCh11N46rGxx0Ue75U3rNap/w6Q3vkWV64Ql/j/XQSE46oYf8SMwlMq78FNq29HMS 5bjwJaQD6H9Sq/0ghnhpTH13eBKgT7hnNTs/csHP9UWPWvxOJ6D+tXrhfzjpunNIhJ7M Wfk2dsdfTfZG+aa/gy07PPfqLYfxS0r/Ph8JnHtuT2LBiYmNCn3G59Erfm6wJEH3b2NG 34ww== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=OQR6wnO5; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 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 lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [2620:137:e000::1:18]) by mx.google.com with ESMTPS id md21-20020a17090b23d500b001bee2a5a5f1si3806551pjb.132.2022.03.08.18.19.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Mar 2022 18:19:10 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) client-ip=2620:137:e000::1:18; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=OQR6wnO5; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 7EA22D10A8; Tue, 8 Mar 2022 17:20:25 -0800 (PST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230082AbiCIBU6 (ORCPT + 99 others); Tue, 8 Mar 2022 20:20:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36354 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230482AbiCIBUT (ORCPT ); Tue, 8 Mar 2022 20:20:19 -0500 Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A4DEEB10A0 for ; Tue, 8 Mar 2022 17:13:19 -0800 (PST) Received: by mail-wr1-x430.google.com with SMTP id p9so668384wra.12 for ; Tue, 08 Mar 2022 17:13:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=jpY2z4H34H3eyBeRRD+CGY7silW4WSqrGPqcmBECpU8=; b=OQR6wnO5d5c3LTMBJooNcShzMDnrZE0ChK/EkciE7eBjvAp9AaNTh8JGyr9hqlIe8o /uLpYB3Sz5zoaFGYFpt6ebZD8vcNRigI2VhxHWkHBGHeMI5X4yVN+av7yUE0A4dksIjT fz6/CovaYl8F+Gl4PS4wx725aQ2QwTOGvwK8bvceboZj1VlrJ6pLLMF2GFGLzX9QXTKt xCSafwiMNAidJBvjoxUwKtaQPB2Qs3FRt0A5UoEpCYNk8OZNYo29CazknewuE2JjVElV 7cesBfsDlrU3roEDItdYH7xJ10SRqQ/6EvLmITBvheW5vavY0ObFtOFW2WTbvIZhGwT0 tfGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=jpY2z4H34H3eyBeRRD+CGY7silW4WSqrGPqcmBECpU8=; b=YwxGU2XlF+8PyqS+NDVjfWEqopBIEXrwkeZ9lM0l1//mw7v41UVKqUKMrBcL+jaa1j nViOSvPZyjV1PlBTvYUIbKGgh/5Ku5RneLBkcfpGPB5le0cfhBHDCQJzCa1Qh/nIkDRn aZ+fjf9X5WebepFjFqkFXKMLnajCaIL7qz8oDsHfv446NV6e/ftNbYeF6KPUYl91HrF/ wV0U4Z1p8OiUS2cOZCrLB65CmneON5j9UXvX9O3pP6amgJNdjc8J16PEJWUewrxTg2IY XR2EzOY0O4Szit0DiWABPE36yC3qf4JB9czJr7kDQT44X/MpYUZz+kkeNUjXblsyvpz1 CFFQ== X-Gm-Message-State: AOAM5318TRvy8R5i4tSTkE9ekXt8oq+D52jSP1geYFQI9sO/h9JYC+mo F7rRTBRgyGRPFlwl6ZIYqmVU7Ia5/fTwOBm6VRU9ErKJwDY= X-Received: by 2002:a5d:6344:0:b0:1f0:21ee:9705 with SMTP id b4-20020a5d6344000000b001f021ee9705mr13967971wrw.93.1646788309356; Tue, 08 Mar 2022 17:11:49 -0800 (PST) MIME-Version: 1.0 References: <20220308131725.60607-1-dmitry.osipenko@collabora.com> <20220308131725.60607-6-dmitry.osipenko@collabora.com> In-Reply-To: <20220308131725.60607-6-dmitry.osipenko@collabora.com> From: Rob Clark Date: Tue, 8 Mar 2022 17:12:18 -0800 Message-ID: Subject: Re: [PATCH v1 5/5] drm/virtio: Add memory shrinker To: Dmitry Osipenko Cc: David Airlie , Gerd Hoffmann , Gurchetan Singh , Chia-I Wu , Daniel Vetter , Daniel Almeida , Gert Wollny , Tomeu Vizoso , Linux Kernel Mailing List , "open list:VIRTIO GPU DRIVER" , Gustavo Padovan , dri-devel , Dmitry Osipenko Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RDNS_NONE, SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Mar 8, 2022 at 5:17 AM Dmitry Osipenko wrote: > > Add memory shrinker and new madvise IOCTL to the VirtIO-GPU driver. > Userspace (BO cache manager of Mesa driver) will mark BOs as "don't need" > using the new IOCTL to let shrinker purge the marked BOs on OOM, thus > shrinker will lower memory pressure and prevent OOM kills. > > Signed-off-by: Daniel Almeida > Signed-off-by: Dmitry Osipenko > --- > drivers/gpu/drm/virtio/Makefile | 3 +- > drivers/gpu/drm/virtio/virtgpu_drv.h | 26 +++- > drivers/gpu/drm/virtio/virtgpu_gem.c | 84 ++++++++++++ > drivers/gpu/drm/virtio/virtgpu_gem_shrinker.c | 124 ++++++++++++++++++ > drivers/gpu/drm/virtio/virtgpu_ioctl.c | 37 ++++++ > drivers/gpu/drm/virtio/virtgpu_kms.c | 10 ++ > drivers/gpu/drm/virtio/virtgpu_object.c | 7 + > drivers/gpu/drm/virtio/virtgpu_plane.c | 17 ++- > drivers/gpu/drm/virtio/virtgpu_vq.c | 15 +++ > include/uapi/drm/virtgpu_drm.h | 14 ++ > 10 files changed, 333 insertions(+), 4 deletions(-) > create mode 100644 drivers/gpu/drm/virtio/virtgpu_gem_shrinker.c > [snip] > diff --git a/drivers/gpu/drm/virtio/virtgpu_gem_shrinker.c b/drivers/gpu/drm/virtio/virtgpu_gem_shrinker.c > new file mode 100644 > index 000000000000..39eb9a3e7e4a > --- /dev/null > +++ b/drivers/gpu/drm/virtio/virtgpu_gem_shrinker.c > @@ -0,0 +1,124 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Copyright (C) 2022 Collabora Ltd. > + */ > + > +#include > +#include > + > +#include "virtgpu_drv.h" > + > +static unsigned long > +virtio_gpu_gem_shrinker_count_objects(struct shrinker *shrinker, > + struct shrink_control *sc) > +{ > + struct drm_gem_shmem_object *shmem; > + struct virtio_gpu_device *vgdev; > + unsigned long count = 0; > + bool empty = true; > + > + vgdev = container_of(shrinker, struct virtio_gpu_device, > + vgshrinker.shrinker); > + > + if (!mutex_trylock(&vgdev->mm_lock)) > + return 0; One bit of advice from previously dealing with shrinker and heavy memory pressure situations (turns out 4GB chromebooks can be pretty much under *constant* memory pressure): You *really* want to make shrinker->count_objects lockless.. and minimize the lock contention on shrinker->scan_objects (ie. The problem is you can end up with shrinking going on on all CPU cores in parallel, you want to not funnel that thru one lock as much as possible. See in particular: 25ed38b3ed26 ("drm/msm: Drop mm_lock in scan loop") cc8a4d5a1bd8 ("drm/msm: Avoid mutex in shrinker_count()") BR, -R > + list_for_each_entry(shmem, &vgdev->vgshrinker.list, madv_list) { > + empty = false; > + > + if (!mutex_trylock(&shmem->pages_lock)) > + continue; > + > + if (drm_gem_shmem_is_purgeable(shmem)) > + count += shmem->base.size >> PAGE_SHIFT; > + > + mutex_unlock(&shmem->pages_lock); > + } > + > + mutex_unlock(&vgdev->mm_lock); > + > + return empty ? SHRINK_EMPTY : count; > +} > + > +static bool virtio_gpu_gem_shrinker_purge(struct virtio_gpu_device *vgdev, > + struct drm_gem_object *obj) > +{ > + struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj); > + struct drm_gem_shmem_object *shmem = &bo->base; > + int err; > + > + if (!dma_resv_test_signaled(obj->resv, true) || > + !drm_gem_shmem_is_purgeable(shmem) || > + refcount_read(&bo->pin_count)) > + return false; > + > + /* > + * Release host's memory before guest's memory is gone to ensure that > + * host won't touch released memory of the guest. > + */ > + err = virtio_gpu_gem_host_mem_release(bo); > + if (err) > + return false; > + > + list_del_init(&shmem->madv_list); > + drm_gem_shmem_purge_locked(shmem); > + > + return true; > +} > + > +static unsigned long > +virtio_gpu_gem_shrinker_scan_objects(struct shrinker *shrinker, > + struct shrink_control *sc) > +{ > + struct drm_gem_shmem_object *shmem, *tmp; > + struct virtio_gpu_device *vgdev; > + unsigned long freed = 0; > + > + vgdev = container_of(shrinker, struct virtio_gpu_device, > + vgshrinker.shrinker); > + > + if (!mutex_trylock(&vgdev->mm_lock)) > + return SHRINK_STOP; > + > + list_for_each_entry_safe(shmem, tmp, &vgdev->vgshrinker.list, madv_list) { > + if (freed >= sc->nr_to_scan) > + break; > + > + if (!dma_resv_trylock(shmem->base.resv)) > + continue; > + > + if (!mutex_trylock(&shmem->pages_lock)) > + goto resv_unlock; > + > + if (virtio_gpu_gem_shrinker_purge(vgdev, &shmem->base)) > + freed += shmem->base.size >> PAGE_SHIFT; > + > + mutex_unlock(&shmem->pages_lock); > +resv_unlock: > + dma_resv_unlock(shmem->base.resv); > + } > + > + mutex_unlock(&vgdev->mm_lock); > + > + return freed; > +} > + > +int virtio_gpu_gem_shrinker_init(struct virtio_gpu_device *vgdev) > +{ > + struct shrinker *shrinker = &vgdev->vgshrinker.shrinker; > + > + shrinker->count_objects = virtio_gpu_gem_shrinker_count_objects; > + shrinker->scan_objects = virtio_gpu_gem_shrinker_scan_objects; > + shrinker->seeks = DEFAULT_SEEKS; > + > + INIT_LIST_HEAD(&vgdev->vgshrinker.list); > + > + return register_shrinker(shrinker); > +} > + > +void virtio_gpu_gem_shrinker_fini(struct virtio_gpu_device *vgdev) > +{ > + struct shrinker *shrinker = &vgdev->vgshrinker.shrinker; > + > + unregister_shrinker(shrinker); > +}