From patchwork Wed Sep 26 16:18:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Hellstrom X-Patchwork-Id: 10616167 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 D66DC14BD for ; Wed, 26 Sep 2018 16:20:45 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C69312B44C for ; Wed, 26 Sep 2018 16:20:45 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C4CAD2B45E; Wed, 26 Sep 2018 16:20:45 +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=BAD_ENC_HEADER,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 A8DE72B450 for ; Wed, 26 Sep 2018 16:20:40 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 782B16E4AD; Wed, 26 Sep 2018 16:19:49 +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-dm3nam03on061e.outbound.protection.outlook.com [IPv6:2a01:111:f400:fe49::61e]) by gabe.freedesktop.org (Postfix) with ESMTPS id 2E6FA6E4B8 for ; Wed, 26 Sep 2018 16:19:30 +0000 (UTC) Received: from localhost.localdomain (155.4.205.56) by DM6PR05MB4588.namprd05.prod.outlook.com (2603:10b6:5:9f::25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1185.14; Wed, 26 Sep 2018 16:19:27 +0000 From: Thomas Hellstrom To: dri-devel@lists.freedesktop.org Subject: [PATCH -next 18/18] drm/vmwgfx: Make user resource lookups reference-free during validation Date: Wed, 26 Sep 2018 18:18:39 +0200 Message-Id: <20180926161839.4549-18-thellstrom@vmware.com> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180926161839.4549-1-thellstrom@vmware.com> References: <20180926161839.4549-1-thellstrom@vmware.com> MIME-Version: 1.0 X-Originating-IP: [155.4.205.56] X-ClientProxiedBy: VI1PR0601CA0020.eurprd06.prod.outlook.com (2603:10a6:800:1e::30) To DM6PR05MB4588.namprd05.prod.outlook.com (2603:10b6:5:9f::25) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 4156dbb2-9d37-4ffd-61f5-08d623cbd58c X-Microsoft-Antispam: BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989299)(4534165)(4627221)(201703031133081)(201702281549075)(8990200)(5600074)(711020)(2017052603328)(7153060)(7193020); SRVR:DM6PR05MB4588; X-Microsoft-Exchange-Diagnostics: 1; DM6PR05MB4588; 3:0segLCw0jHR4Xn4XGGGSRCJ/AoauJHSjtfC0VewaJk5RkbxHwxqe1mLz3CLQJSc9jCPrWjYsunCFpw8ZDb0lg4a3I5bNE49a+If2FteFfW8g6iQ7Hqxqrd/69pD7xyn/aw67eulbQNS/uolzTYSu1FrptuRQ4iqIpxsrPd1L97DZ1o2PyeBOn8SN2pqkAYrrANGsQeO30fpHKqQ3GPAS9lC8K9BEAtykLFzNB4hw2Bv8EWxTRw1QlJxFsQHZTAay; 25:QSdwITP1lzrcofvcDeehXIukg339T0uDfaAx2B07EbRNmhRBwEAmYyI8MP0GJAcTr0vVeFjKlgZwiMzaAdrBbxZcGUtaSuK2ljmlwxWfiOqin8yvjdFdukuTUi6xGnyFEGOKhNZIUUV+yK5lQDJ+bIbBGa5c3cWHH5Z1oTovJy899BNP/wGmTbSqhC1Aj14gWiLubw0hkDxG80ubz++A+1IktNDsTOytknuZYwmMpoqAWpbQ0FfiKeAOL+wOfpx808uXpx7R3AaZgXhS5U4waeVq8AFw0OXS7kZ2OS9D3Q4oGBcZLvXHXZLCwrGOLKtKio5/0Wi3oUQHSNqRAdByRQ==; 31:bnL2GQgaosGZkKDtxWq8R5ChBQFxW61rvDJ1TvD6/gf3Ng2+PdFVBo6NJmyKitv86GRQrFfXo2/x1Trd3wlgj9FEx68v1HbggwgeB2nCWnqOLD0QETRvJQSvgIoIS3jqzS1L6viUd/wrWMzoZQI+p1oA0U+Fd0xjplK3YxG4rzORaRaY/63TKPJ+1PsgEEyOz7jZmsu7ov2muXLwsgcYI8ofCEwJl56b9yIe6tXVEpA= X-MS-TrafficTypeDiagnostic: DM6PR05MB4588: BCL: 0 X-Microsoft-Exchange-Diagnostics: 1; DM6PR05MB4588; 20:S8xtwusCfyjHxMmJosvJ/8rl8YnvQM3IVMcdjawPe2xSsGOa1eWVJSHaKhpkySA3gp0ZMvu2vLlV2c8rPLUjdX3wVwmlGFJYtWXZ8SncYSeduI5fV5Y/9IbUhjyt7acBv2UeVcSvO2pUEEfWg/chKCAprqiUvYTW8kXVPAD5BiyaIUTB8o1qlZQR4i1x0eW2tQTj62EvqC/Y3gdXnFk6I88MyzpPHDVsOOY1UqzhXdeebV/BoNiWiUTwKz/Q5dYwK0LcomZWIXVre92xXJyBRdwAd36XfzV8pRLtsQWO+9dtSRe22SUjx6OqXi+PBRpzUGcW0Cg4gL4VYCcVylnP7/RwcpVCa2ZGf3lVb8CvaJjs0kARQkindDNwiDDsYtGwxH8VRuxgSu/lBawxpDNFEBeMymMwrUdDXjpFHkWTTTtzPVZAYu2H3om7sMGiRnE9s7GG6WMDL4hbs/y+8IzRThWz0k1DYeBO6JN1+GwpvXgEh6hqLZzoXD1m2LrcE9sYTw8cvI9Kie/a4AfuF64R3nkK9VLh/8GplDvEY75AV6HSaQ0ujE0q033A4VLkZdVSqhwW3eoQh/y3XbOIbPkbJJuV3Lo6Pjhm4EYdqLZlugc=; 4:iUnGDigwexW07FQpVXlmcdoZhR7xvcpnmF7g6slOak5yUXK/Ed7sWum7OlwCZ6RKvIEgG5zJ+Q3/UZlGHtZP3TV27rLc9hSAAJE5V71JrAEXH+teC3njRSq+O/IphXtq839Tnxc8WalihMwLo7KOycUL/IyRkzyXmodHoNE2MoA5QopM/75RirRHhVKvAOTo61LApdsJcu/6dwwdXX5VLoSdx7Dso6E6wsXJEAzmVpd8NiX7CQcSuSZNTMgPv0PpjldO1Ptrpy9SptiDnyG+Cm4W+hkNnnwxmxaStRN5zBsPWPrcRf7rxEWEvohmI+ab X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(61668805478150); X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(10201501046)(93006095)(93001095)(3231355)(944501410)(52105095)(3002001)(149066)(150057)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123564045)(20161123558120)(20161123560045)(20161123562045)(201708071742011)(7699051)(76991041); SRVR:DM6PR05MB4588; BCL:0; PCL:0; RULEID:; SRVR:DM6PR05MB4588; X-Forefront-PRVS: 08076ABC99 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(6069001)(1496009)(346002)(376002)(366004)(396003)(136003)(39860400002)(199004)(189003)(11346002)(186003)(105586002)(36756003)(47776003)(26005)(66066001)(6512007)(2351001)(305945005)(14444005)(446003)(2361001)(486006)(16526019)(106356001)(7736002)(5660300001)(476003)(6666003)(53936002)(86362001)(6486002)(575784001)(97736004)(69590400006)(478600001)(68736007)(50466002)(25786009)(8936002)(316002)(16586007)(48376002)(956004)(2616005)(386003)(76176011)(6506007)(3846002)(6916009)(51416003)(1076002)(4326008)(8676002)(81166006)(50226002)(6116002)(107886003)(2906002)(81156014)(52116002)(34290500001); DIR:OUT; SFP:1101; SCL:1; SRVR:DM6PR05MB4588; H:localhost.localdomain; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; A:1; MX:1; Received-SPF: None (protection.outlook.com: vmware.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; DM6PR05MB4588; 23:nJh8wkObViVQsYWax6L8nsxZsU/3zNDur9xdPQOVP?= dQomxGMEZIGTI8uFBdzvTgbDY0mDmAaEPPra5yEW4mlOXBt2DKeuJ34tZj2PluSupjzLHgZovgvsHwTJgzcfULVfue2RvobRE41RAuxBPXtTl+Rudh8mk1Qn64wRjJDApAtjWhNV3iM4xrElKh9Sx+Xui7+SeWGd+oSsAC8DBRXcHokJcR+rW8RRDdpp1TINUEwtBv7xLOyTZkdsWgOwFCH4HZDOgPoRTWvvbLrDKZYGCFlG/P/UxqbSlknivLITXHSfVFFehQ6A0gj0Wc9KIQQjDonGnDCCAuIKJOvxYEcOoUOgnjLR3S1w1OYbbO2a6ZP7alt+xnnae9dRfeqr4R5O0LBotM0rbaGxe9LYqGAsKB+iVbG5Ma09huDi4VB4P+DHoOcP7qHQSb7ChEo8shjF12oI0shxi6GzJMzowd0eonVD0yTBRvo7tVFFzKmwLmVeyE2Mk312f2xr+rdWzTAdxL8joOtwKFQxPDrAoY1Sa6PYJsEhYi3Py1LULXzFncs0bcnX5PpibjFYuoYbjlur8/vfG4z3nGUngpS7LLlj8DDE0se1nt4dVyg3NLu5Bx5hs3yL3P2bB7nAQZWBMprmgrEOLeg7lnGWX9ZLzT3pGu/XiN4A6Dc8sGsiLK6tnXJyut0gV0niVCVNrlERDwTylszIGzpfBz8JAlJS9EgvBuH0IaRGDKQAO1ciabh8NF6G6n9m9sYUOrTz0cgVHKb1T4JgzXcRviq8rkOfwYzcHdZUsywCPQW3SfTdznnUvlWHnwznzI8kBI+zrw3HWU12J3eGmf2dDpd3A6jOA1P22Q9IRfcOH1imCjX/8Cjy9y3cX6T9+FJhX5I62xrfOCC27x7BrZNp3/FtJqzuUQ/g1tu766xIzczzU+iwrFekvrsmzE6kM4RXVQOwK8pNGHTgDdVMXDbHy9ccclVDAVlrB2wgPMhwEBUCgvsiIO5h3Rr22KF8MixE2/alfZpXgYtqjS+kDHGBYegvfPKQZvF2XbUU5a0DygnzAbXFwU0YQ/aNUuw2W2eNOv/eT8g7TV4y18gzisMm4s3q5/uSYtqVPVwIJ5bqJKLd7VVOSs/NRjr3kOjCjyHLZEz+TCJt96qxw1g1VZE6K1ZA9TMWRixqendY4ELFizcla7Eig9nHFcHC9TtDHZCEydw3kLt6NtaxAUip4Jn/KWcFXQYXj/ds4mNqae7VeBrnagBqUIl2Nvh8hwe/4Xx5hbXXKKV+Do6stKTblhUjmP0bNggCLS32AYCc6qM1FidGhKzFKK8ybfLkYpi8juEhlMIK0+2ccX4xqE1KBWPYEE/Dy3ZL51zhtEfSuuFNqQNoCdfejliSe8= X-Microsoft-Antispam-Message-Info: uEcZLRHevHYtAxRvmKwL0iAZpHdDY4l5hseDj/uN65Gzhc1fyqfsDcAPUZ6FXBw+4131Attkx7yvEIkwfdy9JJoogaes3QaUICERs+73Grip22ItLPcJC7861C1tO0WFfJ4R/hSdLwFxhGcj7yx6aiRmfJx4tef9mUYZ8YJZlyrGbm4KnS2TjyoxE9Xxb3nBX3yZBBhWhEOvci8x+chx5N/rHf8jdC2m1Q/+qMNBTlBoxlKXgFHHr0nVn5lVD5bOy1KDdxYKHf6j307Rl+xgO/reXVy2S5+em5MWRrG9MQGS6CxEdxktWn0pFOhy//d+R1rXmmL8Ymu8if43Up2jEv0kueq2s3z93AtEszfQ8Ic= X-Microsoft-Exchange-Diagnostics: 1; DM6PR05MB4588; 6:5vXBWRsBxNemHUTNC3ECkYiclzv3NlxzCTPPT7oSP6GeT+hGQRDMtx3koOIJ+b+DtaXj/sPU64UUKhu4vSdHzLB3pI+X5v8/xRQR3FGcoQuvo6T8FKIjeX42xjoTodtTArlsu+3WTR/kR2l9a2YYiBYMLYZFmxUShg+DI/HKrz+wd5OQ1AkJUoW5naQDT0NWX8RodWJk16ZM0Kg+hqXDsng8fQh7lIlasyJ11BUR3DQrqhdo95gHoF4TQB2qw9y8hPmftNxb0jkTAkWrDm+UlwCuXpPymSWQIdLWwdr4ramXB9+D5H6fPQkuHXGPdElYNspQtEp1qURTRgk431QgR/bVpG7Cki3g2kTH0bleKGbeo71KQ7s5qQzT4+mgfT+VbUoxz6j3mN+XbZrNsdV/VuE76Zoanx4HtGSZuCULq3dtU7vq3Kr9uf8tSYr+73Dxow9AOcWUyc6AYynGyx4A0w==; 5:BMS0rcPqjoAaiBOnea6WXZZZYpvgTbjADiDwn88/bUjiTcK+H6ZqPpHJC00AMc5BY6bkEiDirN3q22fKxOVRbunDagPqNrLNttTVwn6fTzskziDHG7Jl7zjoXHvNYNPB9oi23zJ8wqJVRldZ0ooagUbXVQNCIwvond3pshRmiV4=; 7:VBQH7FMNzwHS2o40XqAEM7ba8O0DzXk4Yf4YR3WTUriWW2r3YKYez73FyQ4+losd6qGOS6UW+miBqhsCEeIDN5PBahQXGqDZcs1VLMN9FrvwriF3REZviy2n+NHSk8VPGvfCMsJelyEuxIQj54w2xBw0RjdbuWmyadW4So6egeVO1vhxxb0yeU9o6Lb+2wjzV9Ul0otMWzrXfo1x0kht1dZGEVIb3zAZ1EO1qIrbcD74M+7kFaIVgSTC0qhluvi/ SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; DM6PR05MB4588; 20:L6cjIgG0VW1q1QYmeEs1YqFBEaa4aQHMt32tOee/txEY1XWX1uCJCwlUl8ADM7IyteqrAfMJgtvxYP4ueOWYwbptZ0X8slm3OFvDOH919BfJVTroA8Et8V0lttWSwMawSQwRNNW3Tf3jNhFawO4ye0Thj5X9EFeyn3ldxDLT978= X-OriginatorOrg: vmware.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 26 Sep 2018 16:19:27.9218 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 4156dbb2-9d37-4ffd-61f5-08d623cbd58c X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: b39138ca-3cee-4b4a-a4d6-cd83d9dd62f0 X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR05MB4588 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: Thomas Hellstrom , linux-graphics-maintainer@vmware.com Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Make the process of looking up a user resource and adding it to the validation list reference-free unless when it's actually added to the validation list where a single reference is taken. This saves two locked atomic operations per command stream buffer object handle lookup, unless there is a lookup cache hit. Signed-off-by: Thomas Hellstrom Reviewed-by: Sinclair Yeh --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 18 ++- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 267 ++++++++++++++++--------------- drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 35 ++++ 3 files changed, 187 insertions(+), 133 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index ebb2ae86d900..2283bfb97f81 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -337,8 +337,6 @@ struct vmw_ctx_validation_info; * @last_query_ctx: Last context that submitted a query * @needs_post_query_barrier: Whether a query barrier is needed after * command submission - * @error_resource: Pointer to hold a reference to the resource causing - * an error * @staged_bindings: Cached per-context binding tracker * @staged_bindings_inuse: Whether the cached per-context binding tracker * is in use @@ -365,7 +363,6 @@ struct vmw_sw_context{ struct vmw_res_cache_entry res_cache[vmw_res_max]; struct vmw_resource *last_query_ctx; bool needs_post_query_barrier; - struct vmw_resource *error_resource; struct vmw_ctx_binding_state *staged_bindings; bool staged_bindings_inuse; struct list_head staged_cmd_res; @@ -698,6 +695,12 @@ extern int vmw_user_resource_lookup_handle( uint32_t handle, const struct vmw_user_resource_conv *converter, struct vmw_resource **p_res); +extern struct vmw_resource * +vmw_user_resource_noref_lookup_handle(struct vmw_private *dev_priv, + struct ttm_object_file *tfile, + uint32_t handle, + const struct vmw_user_resource_conv * + converter); extern int vmw_stream_claim_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int vmw_stream_unref_ioctl(struct drm_device *dev, void *data, @@ -716,6 +719,15 @@ extern int vmw_query_readback_all(struct vmw_buffer_object *dx_query_mob); extern void vmw_resource_evict_all(struct vmw_private *dev_priv); extern void vmw_resource_unbind_list(struct vmw_buffer_object *vbo); +/** + * vmw_user_resource_noref_release - release a user resource pointer looked up + * without reference + */ +static inline void vmw_user_resource_noref_release(void) +{ + ttm_base_object_noref_release(); +} + /** * Buffer object helper functions - vmwgfx_bo.c */ diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index dfa2d19274d5..5a6b70ba137a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -230,16 +230,55 @@ static int vmw_cmd_ctx_first_setup(struct vmw_private *dev_priv, } /** - * vmw_resource_val_add - Add a resource to the software context's - * resource list if it's not already on it. + * vmw_execbuf_res_size - calculate extra size fore the resource validation + * node + * @dev_priv: Pointer to the device private struct. + * @res_type: The resource type. * - * @sw_context: Pointer to the software context. + * Guest-backed contexts and DX contexts require extra size to store + * execbuf private information in the validation node. Typically the + * binding manager associated data structures. + * + * Returns: The extra size requirement based on resource type. + */ +static unsigned int vmw_execbuf_res_size(struct vmw_private *dev_priv, + enum vmw_res_type res_type) +{ + return (res_type == vmw_res_dx_context || + (res_type == vmw_res_context && dev_priv->has_mob)) ? + sizeof(struct vmw_ctx_validation_info) : 0; +} + +/** + * vmw_execbuf_rcache_update - Update a resource-node cache entry + * + * @rcache: Pointer to the entry to update. * @res: Pointer to the resource. - * @p_node On successful return points to a valid pointer to a - * struct vmw_resource_val_node, if non-NULL on entry. + * @private: Pointer to the execbuf-private space in the resource + * validation node. */ -static int vmw_resource_val_add(struct vmw_sw_context *sw_context, - struct vmw_resource *res) +static void vmw_execbuf_rcache_update(struct vmw_res_cache_entry *rcache, + struct vmw_resource *res, + void *private) +{ + rcache->res = res; + rcache->private = private; + rcache->valid = 1; + rcache->valid_handle = 0; +} + +/** + * vmw_execbuf_res_noref_val_add - Add a resource described by an + * unreferenced rcu-protected pointer to the validation list. + * @sw_context: Pointer to the software context. + * @res: Unreferenced rcu-protected pointer to the resource. + * + * Returns: 0 on success. Negative error code on failure. Typical error + * codes are %-EINVAL on inconsistency and %-ESRCH if the resource was + * doomed. + */ +static int vmw_execbuf_res_noref_val_add(struct vmw_sw_context *sw_context, + struct vmw_resource *res) { struct vmw_private *dev_priv = res->dev_priv; int ret; @@ -247,18 +286,18 @@ static int vmw_resource_val_add(struct vmw_sw_context *sw_context, struct vmw_res_cache_entry *rcache; struct vmw_ctx_validation_info *ctx_info; bool first_usage; - size_t priv_size; + unsigned int priv_size; - /* - * If the resource is a context, set up structures to track - * context bindings. - */ - priv_size = (res_type == vmw_res_dx_context || - (res_type == vmw_res_context && dev_priv->has_mob)) ? - sizeof(*ctx_info) : 0; + rcache = &sw_context->res_cache[res_type]; + if (likely(rcache->valid && rcache->res == res)) { + vmw_user_resource_noref_release(); + return 0; + } + priv_size = vmw_execbuf_res_size(dev_priv, res_type); ret = vmw_validation_add_resource(sw_context->ctx, res, priv_size, (void **)&ctx_info, &first_usage); + vmw_user_resource_noref_release(); if (ret) return ret; @@ -269,14 +308,37 @@ static int vmw_resource_val_add(struct vmw_sw_context *sw_context, return ret; } - /* Cache info about the last added resource */ + vmw_execbuf_rcache_update(rcache, res, ctx_info); + return 0; +} + +/** + * vmw_execbuf_res_noctx_val_add - Add a non-context resource to the resource + * validation list if it's not already on it + * @sw_context: Pointer to the software context. + * @res: Pointer to the resource. + * + * Returns: Zero on success. Negative error code on failure. + */ +static int vmw_execbuf_res_noctx_val_add(struct vmw_sw_context *sw_context, + struct vmw_resource *res) +{ + struct vmw_res_cache_entry *rcache; + enum vmw_res_type res_type = vmw_res_type(res); + void *ptr; + int ret; + rcache = &sw_context->res_cache[res_type]; - rcache->res = res; - rcache->private = ctx_info; - rcache->valid = 1; - rcache->valid_handle = 0; + if (likely(rcache->valid && rcache->res == res)) + return 0; - return ret; + ret = vmw_validation_add_resource(sw_context->ctx, res, 0, &ptr, NULL); + if (ret) + return ret; + + vmw_execbuf_rcache_update(rcache, res, ptr); + + return 0; } /** @@ -297,11 +359,11 @@ static int vmw_view_res_val_add(struct vmw_sw_context *sw_context, * First add the resource the view is pointing to, otherwise * it may be swapped out when the view is validated. */ - ret = vmw_resource_val_add(sw_context, vmw_view_srf(view)); + ret = vmw_execbuf_res_noctx_val_add(sw_context, vmw_view_srf(view)); if (ret) return ret; - return vmw_resource_val_add(sw_context, view); + return vmw_execbuf_res_noctx_val_add(sw_context, view); } /** @@ -371,7 +433,7 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv, if (IS_ERR(res)) continue; - ret = vmw_resource_val_add(sw_context, res); + ret = vmw_execbuf_res_noctx_val_add(sw_context, res); if (unlikely(ret != 0)) return ret; } @@ -383,16 +445,11 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv, binding_list = vmw_context_binding_list(ctx); list_for_each_entry(entry, binding_list, ctx_list) { - /* entry->res is not refcounted */ - res = vmw_resource_reference_unless_doomed(entry->res); - if (unlikely(res == NULL)) - continue; - if (vmw_res_type(entry->res) == vmw_res_view) ret = vmw_view_res_val_add(sw_context, entry->res); else - ret = vmw_resource_val_add(sw_context, entry->res); - vmw_resource_unreference(&res); + ret = vmw_execbuf_res_noctx_val_add(sw_context, + entry->res); if (unlikely(ret != 0)) break; } @@ -534,38 +591,6 @@ static int vmw_resources_reserve(struct vmw_sw_context *sw_context) return ret; } -/** - * vmw_cmd_res_reloc_add - Add a resource to a software context's - * relocation- and validation lists. - * @dev_priv: Pointer to a struct vmw_private identifying the device. - * @sw_context: Pointer to the software context. - * @id_loc: Pointer to where the id that needs translation is located. - * @res: Valid pointer to a struct vmw_resource. - * - * Return: Zero on success, negative error code on error - */ -static int vmw_cmd_res_reloc_add(struct vmw_private *dev_priv, - struct vmw_sw_context *sw_context, - uint32_t *id_loc, - struct vmw_resource *res) -{ - int ret; - - ret = vmw_resource_relocation_add(sw_context, res, - vmw_ptr_diff(sw_context->buf_start, - id_loc), - vmw_res_rel_normal); - if (unlikely(ret != 0)) - return ret; - - ret = vmw_resource_val_add(sw_context, res); - if (unlikely(ret != 0)) - return ret; - - return 0; -} - - /** * vmw_cmd_res_check - Check that a resource is present and if so, put it * on the resource validate list unless it's already there. @@ -587,8 +612,7 @@ vmw_cmd_res_check(struct vmw_private *dev_priv, uint32_t *id_loc, struct vmw_resource **p_res) { - struct vmw_res_cache_entry *rcache = - &sw_context->res_cache[res_type]; + struct vmw_res_cache_entry *rcache = &sw_context->res_cache[res_type]; struct vmw_resource *res; int ret; @@ -603,56 +627,41 @@ vmw_cmd_res_check(struct vmw_private *dev_priv, return 0; } - /* - * Fastpath in case of repeated commands referencing the same - * resource - */ - if (likely(rcache->valid_handle && *id_loc == rcache->handle)) { - struct vmw_resource *res = rcache->res; + res = rcache->res; + } else { + unsigned int size = vmw_execbuf_res_size(dev_priv, res_type); - if (p_res) - *p_res = res; + ret = vmw_validation_preload_res(sw_context->ctx, size); + if (ret) + return ret; - return vmw_resource_relocation_add - (sw_context, res, - vmw_ptr_diff(sw_context->buf_start, id_loc), - vmw_res_rel_normal); - } + res = vmw_user_resource_noref_lookup_handle + (dev_priv, sw_context->fp->tfile, *id_loc, converter); + if (unlikely(IS_ERR(res))) { + DRM_ERROR("Could not find or use resource 0x%08x.\n", + (unsigned int) *id_loc); + return PTR_ERR(res); + } - ret = vmw_user_resource_lookup_handle(dev_priv, - sw_context->fp->tfile, - *id_loc, - converter, - &res); - if (unlikely(ret != 0)) { - DRM_ERROR("Could not find or use resource 0x%08x.\n", - (unsigned) *id_loc); - dump_stack(); - return ret; - } + ret = vmw_execbuf_res_noref_val_add(sw_context, res); + if (unlikely(ret != 0)) + return ret; - ret = vmw_cmd_res_reloc_add(dev_priv, sw_context, id_loc, - res); - if (unlikely(ret != 0)) - goto out_no_reloc; + if (rcache->valid && rcache->res == res) { + rcache->valid_handle = true; + rcache->handle = *id_loc; + } + } + ret = vmw_resource_relocation_add(sw_context, res, + vmw_ptr_diff(sw_context->buf_start, + id_loc), + vmw_res_rel_normal); if (p_res) *p_res = res; - if (rcache->valid && rcache->res == res) { - rcache->valid_handle = true; - rcache->handle = *id_loc; - } - - vmw_resource_unreference(&res); return 0; - -out_no_reloc: - BUG_ON(sw_context->error_resource != NULL); - sw_context->error_resource = res; - - return ret; } /** @@ -854,9 +863,9 @@ static int vmw_cmd_set_render_target_check(struct vmw_private *dev_priv, return ret; ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, - user_surface_converter, - &cmd->body.target.sid, &res); - if (unlikely(ret != 0)) + user_surface_converter, &cmd->body.target.sid, + &res); + if (unlikely(ret)) return ret; if (dev_priv->has_mob) { @@ -890,8 +899,8 @@ static int vmw_cmd_surface_copy_check(struct vmw_private *dev_priv, cmd = container_of(header, struct vmw_sid_cmd, header); ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, - user_surface_converter, - &cmd->body.src.sid, NULL); + user_surface_converter, + &cmd->body.src.sid, NULL); if (ret) return ret; @@ -2127,8 +2136,7 @@ static int vmw_cmd_set_shader(struct vmw_private *dev_priv, cmd->body.type); if (!IS_ERR(res)) { - ret = vmw_cmd_res_reloc_add(dev_priv, sw_context, - &cmd->body.shid, res); + ret = vmw_execbuf_res_noctx_val_add(sw_context, res); if (unlikely(ret != 0)) return ret; } @@ -2345,7 +2353,7 @@ static int vmw_cmd_dx_set_shader(struct vmw_private *dev_priv, return PTR_ERR(res); } - ret = vmw_resource_val_add(sw_context, res); + ret = vmw_execbuf_res_noctx_val_add(sw_context, res); if (ret) return ret; } @@ -2883,13 +2891,12 @@ static int vmw_cmd_dx_bind_shader(struct vmw_private *dev_priv, return PTR_ERR(res); } - ret = vmw_resource_val_add(sw_context, res); + ret = vmw_execbuf_res_noctx_val_add(sw_context, res); if (ret) { DRM_ERROR("Error creating resource validation node.\n"); return ret; } - return vmw_cmd_res_switch_backup(dev_priv, sw_context, res, &cmd->body.mobid, cmd->body.offsetInBytes); @@ -3781,28 +3788,33 @@ static int vmw_execbuf_tie_context(struct vmw_private *dev_priv, { struct vmw_resource *res; int ret; + unsigned int size; if (handle == SVGA3D_INVALID_ID) return 0; - ret = vmw_user_resource_lookup_handle(dev_priv, sw_context->fp->tfile, - handle, user_context_converter, - &res); - if (unlikely(ret != 0)) { + size = vmw_execbuf_res_size(dev_priv, vmw_res_dx_context); + ret = vmw_validation_preload_res(sw_context->ctx, size); + if (ret) + return ret; + + res = vmw_user_resource_noref_lookup_handle + (dev_priv, sw_context->fp->tfile, handle, + user_context_converter); + if (unlikely(IS_ERR(res))) { DRM_ERROR("Could not find or user DX context 0x%08x.\n", (unsigned) handle); - return ret; + return PTR_ERR(res); } - ret = vmw_resource_val_add(sw_context, res); + ret = vmw_execbuf_res_noref_val_add(sw_context, res); if (unlikely(ret != 0)) - goto out_err; + return ret; sw_context->dx_ctx_node = vmw_execbuf_info_from_res(sw_context, res); sw_context->man = vmw_context_res_man(res); -out_err: - vmw_resource_unreference(&res); - return ret; + + return 0; } int vmw_execbuf_process(struct drm_file *file_priv, @@ -3818,7 +3830,6 @@ int vmw_execbuf_process(struct drm_file *file_priv, { struct vmw_sw_context *sw_context = &dev_priv->ctx; struct vmw_fence_obj *fence = NULL; - struct vmw_resource *error_resource; struct vmw_cmdbuf_header *header; uint32_t handle; int ret; @@ -4028,8 +4039,6 @@ int vmw_execbuf_process(struct drm_file *file_priv, !dev_priv->query_cid_valid)) __vmw_execbuf_release_pinned_bo(dev_priv, NULL); out_unlock: - error_resource = sw_context->error_resource; - sw_context->error_resource = NULL; vmw_cmdbuf_res_revert(&sw_context->staged_cmd_res); vmw_validation_drop_ht(&val_ctx); WARN_ON(!list_empty(&sw_context->ctx_list)); @@ -4040,8 +4049,6 @@ int vmw_execbuf_process(struct drm_file *file_priv, * avoid deadlocks in resource destruction paths. */ vmw_validation_unref_lists(&val_ctx); - if (unlikely(error_resource != NULL)) - vmw_resource_unreference(&error_resource); out_free_header: if (header) vmw_cmdbuf_header_free(header); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index cf48d0b157f6..8a029bade32a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c @@ -230,6 +230,41 @@ int vmw_user_resource_lookup_handle(struct vmw_private *dev_priv, return ret; } +/** + * vmw_user_resource_lookup_handle - lookup a struct resource from a + * TTM user-space handle and perform basic type checks + * + * @dev_priv: Pointer to a device private struct + * @tfile: Pointer to a struct ttm_object_file identifying the caller + * @handle: The TTM user-space handle + * @converter: Pointer to an object describing the resource type + * @p_res: On successful return the location pointed to will contain + * a pointer to a refcounted struct vmw_resource. + * + * If the handle can't be found or is associated with an incorrect resource + * type, -EINVAL will be returned. + */ +struct vmw_resource * +vmw_user_resource_noref_lookup_handle(struct vmw_private *dev_priv, + struct ttm_object_file *tfile, + uint32_t handle, + const struct vmw_user_resource_conv + *converter) +{ + struct ttm_base_object *base; + + base = ttm_base_object_noref_lookup(tfile, handle); + if (!base) + return ERR_PTR(-ESRCH); + + if (unlikely(ttm_base_object_type(base) != converter->object_type)) { + ttm_base_object_noref_release(); + return ERR_PTR(-EINVAL); + } + + return converter->base_obj_to_res(base); +} + /** * Helper function that looks either a surface or bo. *