From patchwork Wed Sep 26 16:18:26 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Hellstrom X-Patchwork-Id: 10616149 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 8468F14BD for ; Wed, 26 Sep 2018 16:19:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 77DB02B3D5 for ; Wed, 26 Sep 2018 16:19:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6A3BA2B3DA; Wed, 26 Sep 2018 16:19:50 +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 714DD2B3D5 for ; Wed, 26 Sep 2018 16:19:49 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1AA476E4A4; Wed, 26 Sep 2018 16:19:19 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from NAM04-BN3-obe.outbound.protection.outlook.com (mail-bn3nam04on0621.outbound.protection.outlook.com [IPv6:2a01:111:f400:fe4e::621]) by gabe.freedesktop.org (Postfix) with ESMTPS id 260A16E499 for ; Wed, 26 Sep 2018 16:19:13 +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:10 +0000 From: Thomas Hellstrom To: dri-devel@lists.freedesktop.org Subject: [PATCH -next 05/18] drm/vmwgfx: Use a validation context allocator for relocations and validations Date: Wed, 26 Sep 2018 18:18:26 +0200 Message-Id: <20180926161839.4549-5-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: 2ff2d161-11f5-419d-78c4-08d623cbcb2d 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:/HIzcdCk0pCGiFnXMZo5vcUMSg6yLRCK1rcWXeLacoE6YHZFU6MDR9T4NVGoXUtHiEzOim09qFwhHERB0OmlB9i5Z31hVJsyucA+tDbYH5w5btxMdAj1amAl3oBAbGnEOJNoDjLEz9iXJm3AGBEZWIDMNfaXslsQLqwoZOnMnoxJXTjzXajrdJU9MvOqDtVUVb2c4ds20LndOOEtxQh8JtLglu5IjWXS2UyPP0Lfg4fivTwG3pez8LCtNPLFaa2x; 25:5RdNuDbD2/yzeMSHCZ8PYmEF8T4bsxjwaKzyhVo1R9cWMmi840a/q5+DYHofnyUuw/1bgdD61fW9wDCKXtGuuoW32nmcgVHoZNpBea4m+4d0qcH9wKHqxqEkGV5iMgZ3np/KvLb82egzGoFBjw3xs0xLqelOcit8riqg8FAVBXd14Yib3D8nfJxrMIV5D0HwZ7Rjr32BWp4ThmY/KjM/uIZWt7Fiqpv7wnmcesPoTVJulN7v5QIQ7jRluSdRDQ6YpDnWxlgANSHXJHONgdurIKx9NfqRYGlejghXoRYow9PciccF/+fMpCjYO9N6/oqpfmFPSAtUgv+vcKkOn5o22A==; 31:dDozi+JRP38uWOgzHkjjoS0UZ5LOwtMij35leRGXi2iUu/3QF56VezRu7N1iy72JnssRYGkcSTxZnGT7+gSZelGFECHr0t+jplcbZ2X+5xnxJtfFHdHUHM5HVVPd+6Kf/Cg3/Qoyge99vDKZoSZ0H6v9tpqk3EWcTTYoor4wFrmiyN45kof1gXP+4c3z9PhI0BsYPgnjvvM3K70Bgv7wmEUgPUj5bHnE+4+RbOomE0o= X-MS-TrafficTypeDiagnostic: DM6PR05MB4588: BCL: 0 X-Microsoft-Exchange-Diagnostics: 1; DM6PR05MB4588; 20:B3syosSGQ/seGE/mU6XX6AaPvT3Ezn5dXKec0WsBpsGpljFCkgQhqQMGy5TJa95cihcbVHyOmYtkwHGRt1gPf/i3wgPh/tM9svH6R3B4u5CHR73eyPQjUeT3MvVyXdUF83XNS1JenRYaJf5BEc8bfc0CF4u+Wg3oIOMphPTXxxsVIrofUiwjVcEccqfCUDnuYgJbfZ2SvF/OziICXnMpC1CfFdAIMDFJx+UfjLBnBPo2mvdrvnXIl6jukdQtOpyC+c9VxiIISblNLia/NhvJBXDusd55xaY6x69XFybLGPMXa8a9LKc57zZ3LP22MIO/jyKCvYLTUy6/0cbtO3OHLVOx14Y16071yf8Hh4rlMo3mVdhTU+y6KkBIL+eJcbHMIE0FTirca26RhGlu4qREg9WGfFOxarKZGRD9Z/W8RHaOUMVrOqszlCrE7eS0X3WdMXxxveJEHM4fG+/OSr6Ix0H6IeUv+zZJzkfau/kfhTPgbroRQw9xy4a2Mc0R6kx2iwfDSln7KbI5cjYZRZR7V2ojG3owRePQgTNXET52ot7YTYJuLyoCW0bJx7N8GKXLwdL40J2J61wKxI1OduUyKeI7jifU+hKQOLF6OHmpi4Q=; 4:yGz7Zy35zIlZ6Jv3BpMqxu/DjmFNxaR88RC0x81yU0MkyIO41nm2XrPqMqDrhNJSVU3gKhSvx+SNjUS7QFj2t0cWRtandUIvuiQ/U9prL+L1VFJIqS6iXCF+YMSfl/fEfXWAykd22k/s4bnLZkbGveYh7zCrmsL4bcauK4M5rcB4x+T0nxbVcmHu5yXh1ugbBDuvYfXHeQUooJ4gp6ugg5zLbzTLppniEZdFnwXW8Wse5LBIBdTMuT7KzRcybgv1tHNgOtnx9tUPI4v3idLoiqEpaW3IWl27waN9FfWXz0yaQ6lZwDCyf74LO+6U4tHb 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)(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:2wQlArtY0dg+h3JqxScFY98d0A+OmDsiiENfRvFpY?= 8JOSjSVrBjiWtlBQfK8mVBRQ/kL11+dBv1BPIQSY+iBHl3PBdhyUYodlakoliLseGYpfUzPaEKmEtSJi7odF3hBXVxiOBjWfDCWZ/NLlOa9bcKrMX5EkDvWI5YxnUxJzRw/a0mn2ppsKWCslgR5fxZ4+2yZgBaWoVO+5zTHkkR1TCvU1r44Odl8BYWMVKZBkrCEe0kQ/wgYv4lMoudhiGgmbTX/v7SHQYnKVRS8iJerXE+VrC5qp+FQGWoxdAz+4WtzVmbXMROckuGMWkqlEH1hDM+httNt6OirSBPQr8HmTLRZY9NtE7NO3Rh6H9rNuEawfnExV7FJjF2V0uLyVTdYihmccEhyVuCA2ihbb234/y2gelync2k0kl+4H9rO+p57BpTTy027ESBQi9Z+ukcJgrd54wBHDh6BueWfN6BEMvJlphUeW4IBInQzz0AR4mCxcwqmSr+PoLbhcToE+0l5VzPO153GPN62RZS5uJqDmNippg+T/F/sFvp7rG3g3jOu3mfxxj6BrjzYfg2qfXnzgXO68i+lW9A7FePBVlC0ERCxH6EGEBvxCos6PRHE1doikBeRG5UupBfBbyEFn/FbtKoebzT4H4d6oNdIXXNU4EFzbxQ04QpNu+88FqRCdrC/JOLPG6KgvtsdLopjIIxE3+4WMl3KSM0+BcZnTTwovQiAEplgJMrbqKZs1iHjY/BtXFEv2t8hprRtGmG9kZAFunNB0sXgnckTaHQdpimBTYa6Gs0pUYNzbksIbB7//ng6Kb2GwTsLZnFf10IGpJjbji1GKg2inrRtuJxvhInkOuDYju2DGhk1Mn2hHPFtzw5IwGXTbg4PajQ7e8XEJEeTqZGw+BOyBGudVbthJjJ16kJsdbt4OLYfTQwAj1NX6+S97tx0/FULOcQBTSpwhGRXS25uBAx9DdUh4pHvh0Al1FLOJfpdPycycm8oz3nqiknCM0wGW2pOgBo4wR4CAi2FQbKekoz+DUIYEc6VD/jNTcSMJTV6NT8ccOg2t5h7tNntEsL2LbFTvEs57G7gI3j1jYfd7I+NEoZqlPRqe5737hD9GOExhQMKtgCC1r1OajuPphuxSSU0ANOrXwDv0+b8B6PvMtpdArMc+sS53+U1v4Gdn9M8BNg4E27UTCSn8OiznN/Z9AmO6ZYtQUIWU3moABXPrUaUBjmmBKoLRRlgXG2b6dLygrBpn5CC3FzpIbYIkW+b/vvY036IAnsG5UNyMeRiGcuDWY3+WxHKwJE1tkFA8Hb1soELIB49ov/J4L5IDvOm4wdPWzu+Vm3fyQNBFqgpfFUgCuNhedvlrbfvQA== X-Microsoft-Antispam-Message-Info: T7kX6THu/DUCYJF7t+Xi4atkY1ENXw54Ob+piqJEkfNfHt7DiYvS5725pDSQly3x/S6n6aKrThhbs6HmO8kLZ71O7+sdmLmRtfPqzLA0dPLQ+bV5+FQvctia5EHGtjibvgFt+iJQJ3jOwfoXaUv0aO810wOYktpf1diwzwjLGhKSbdVlmbZNtai0K7CQK6GK02GAnnPrsURIhokmlxVeHO1LgVYue1fb1Ddn66cqpUjf6U19rXMplmWrYWTH+Haa55AicfE3ZkwYBuAEy8iKxts+bgZImEvJgZ9zm9JOIJygxf0LTfapIM/mcGJxNL8ziDwxxtNAG4PzUNBWsOvwiF/dlkFoiWFguMJP6nMlXVw= X-Microsoft-Exchange-Diagnostics: 1; DM6PR05MB4588; 6:f1hutB+hXJ/pMeWnU178irxFTEa8I1UG1mMmESkq/4TV3OOThDa+cW+fDksVVRl+aL2H2gaCIthWntpu+5UhKXXYVG5VFUroY7I5d+H7oWsvcuXfkmLfqD841PB4+EZxkzQewTINo2Intzr0mT6xMuG0T2+6iXivhR42baOlUJDCEB/LgkJ3JpmlBGC3YzLPiK6O7pSWHY/9Ol2+nDCqLbbT79RXLhT8ynlS0h4zRQX+FFFB5Uk4byOBMXjmP+J0AnCdcHQQS0KQ3IEc+fPO8OvfuPFIeOLQr0RUZlUFC1lG2WMzt+ZllqpjbLrLvJTyzIDQZlNk37PiqVEjvMSEwHFXXEAEmxfJbsiC+eooPcuugrXBnIubpOd52Pl2wjXzqC32SK52LxXoaQ3dhkPspCP+9NStfBmTk/N1DYxP71V4HxwHhp8OQm+faA7MhuslXkq8uNhX7Mz9gxtZ6gpMIw==; 5:hip8Lw0VfRMmwe1UVfLedf9tShWgRIVE6ryT7joHFh4TPgHE81rZxMV0dckPGPcJpOgjPlnU2zKieABtgSsNxyBncsyK98jO0LIyXbazAncuN8WGroupicM9RsRLOIPYir9JUR3D65p7e4x/+SDx9SO7+d4WAcl6UZPPUQGzG24=; 7:x+rWABmj3oqMi4Ox8HVO/xpNAesDTinBfxfAdrkm7Od05Kn8CEhuPC1rFdiwyOFYp0SGJlxvy9ZCTbiS+5KqFoX0JtCN8LTDi/pUqzZ5HiMlpj6c58Vl9bzUtkNh90OAYwi8IlD1lnZ7QkvFHhdIigDh34lrPXfignSkBhSKlqECuXzOaI5NRcvge3TZzMR5pgJ5Da8pAM64NsB07naoMP30t/gE7LipxGV2UXMWfzn7tXzFV+OGoWDQuYcuxL/w SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; DM6PR05MB4588; 20:g67huXvWJ0qypVs1KZyKLa6WZKR13rlzDe6EGNpRaGOf3IQGiHsFeWVYKE9n4cuZydWBte/+8vCdd1bcnImnHp84HnuLXcKymq1lOI+XnUrCcLFc47pszSSZCMwTr6Jf/lw/Fn3lw+tpqarwou7T+GB57HCZ1IZftzDVNAcmS04= X-OriginatorOrg: vmware.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 26 Sep 2018 16:19:10.5226 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 2ff2d161-11f5-419d-78c4-08d623cbcb2d 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 A common trait of these objects are that they are allocated during the command validation phase and freed after command submission. Furthermore they are accessed by a single thread only. So provide a simple unprotected stack-like allocator from which these objects can be allocated. Their memory is freed with the validation context when the command submission is done. Note that the mm subsystem maintains a per-cpu cache of single pages to make single page allocation and freeing efficient. Signed-off-by: Thomas Hellstrom Reviewed-by: Sinclair Yeh --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 12 +--- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 80 ++++++++++++++------------ drivers/gpu/drm/vmwgfx/vmwgfx_validation.c | 92 ++++++++++++++++++++++++------ drivers/gpu/drm/vmwgfx/vmwgfx_validation.h | 12 +++- 4 files changed, 132 insertions(+), 64 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 5ff50972c3a1..2f46e5613dfb 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -205,12 +205,6 @@ struct vmw_fifo_state { bool dx; }; -struct vmw_relocation { - SVGAMobId *mob_loc; - SVGAGuestPtr *location; - struct vmw_buffer_object *vbo; -}; - /** * struct vmw_res_cache_entry - resource information cache entry * @handle: User-space handle of a resource. @@ -303,12 +297,11 @@ struct vmw_ctx_validation_info; * than from user-space * @fp: If @kernel is false, points to the file of the client. Otherwise * NULL - * @relocs: Array of buffer object relocations - * @cur_reloc: Cursor pointing to the current relocation * @cmd_bounce: Command bounce buffer used for command validation before * copying to fifo space * @cmd_bounce_size: Current command bounce buffer size * @cur_query_bo: Current buffer object used as query result buffer + * @bo_relocations: List of buffer object relocations * @res_relocations: List of resource relocations * @buf_start: Pointer to start of memory where command validation takes * place @@ -335,11 +328,10 @@ struct vmw_sw_context{ bool res_ht_initialized; bool kernel; struct vmw_fpriv *fp; - struct vmw_relocation relocs[VMWGFX_MAX_RELOCATIONS]; - uint32_t cur_reloc; uint32_t *cmd_bounce; uint32_t cmd_bounce_size; struct vmw_buffer_object *cur_query_bo; + struct list_head bo_relocations; struct list_head res_relocations; uint32_t *buf_start; struct vmw_res_cache_entry res_cache[vmw_res_max]; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 85821a5b227c..da341cc6ff47 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -35,6 +35,21 @@ #define VMW_RES_HT_ORDER 12 +/* + * struct vmw_relocation - Buffer object relocation + * + * @head: List head for the command submission context's relocation list + * @mob_loc: Pointer to location for mob id to be modified + * @location: Pointer to location for guest pointer to be modified + * @vbo: Non ref-counted pointer to buffer object + */ +struct vmw_relocation { + struct list_head head; + SVGAMobId *mob_loc; + SVGAGuestPtr *location; + struct vmw_buffer_object *vbo; +}; + /** * enum vmw_resource_relocation_type - Relocation type for resources * @@ -132,11 +147,9 @@ static size_t vmw_ptr_diff(void *a, void *b) static void vmw_execbuf_bindings_commit(struct vmw_sw_context *sw_context, bool backoff) { - struct vmw_ctx_validation_info *entry, *next; - - list_for_each_entry_safe(entry, next, &sw_context->ctx_list, head) { - list_del(&entry->head); + struct vmw_ctx_validation_info *entry; + list_for_each_entry(entry, &sw_context->ctx_list, head) { if (!backoff) vmw_binding_state_commit(entry->cur, entry->staged); if (entry->staged != sw_context->staged_bindings) @@ -144,6 +157,9 @@ static void vmw_execbuf_bindings_commit(struct vmw_sw_context *sw_context, else sw_context->staged_bindings_inuse = false; } + + /* List entries are freed with the validation context */ + INIT_LIST_HEAD(&sw_context->ctx_list); } /** @@ -397,7 +413,7 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv, * id that needs fixup is located. Granularity is one byte. * @rel_type: Relocation type. */ -static int vmw_resource_relocation_add(struct list_head *list, +static int vmw_resource_relocation_add(struct vmw_sw_context *sw_context, const struct vmw_resource *res, unsigned long offset, enum vmw_resource_relocation_type @@ -405,7 +421,7 @@ static int vmw_resource_relocation_add(struct list_head *list, { struct vmw_resource_relocation *rel; - rel = kmalloc(sizeof(*rel), GFP_KERNEL); + rel = vmw_validation_mem_alloc(sw_context->ctx, sizeof(*rel)); if (unlikely(!rel)) { DRM_ERROR("Failed to allocate a resource relocation.\n"); return -ENOMEM; @@ -414,7 +430,7 @@ static int vmw_resource_relocation_add(struct list_head *list, rel->res = res; rel->offset = offset; rel->rel_type = rel_type; - list_add_tail(&rel->head, list); + list_add_tail(&rel->head, &sw_context->res_relocations); return 0; } @@ -422,16 +438,13 @@ static int vmw_resource_relocation_add(struct list_head *list, /** * vmw_resource_relocations_free - Free all relocations on a list * - * @list: Pointer to the head of the relocation list. + * @list: Pointer to the head of the relocation list */ static void vmw_resource_relocations_free(struct list_head *list) { - struct vmw_resource_relocation *rel, *n; + /* Memory is validation context memory, so no need to free it */ - list_for_each_entry_safe(rel, n, list, head) { - list_del(&rel->head); - kfree(rel); - } + INIT_LIST_HEAD(list); } /** @@ -532,8 +545,7 @@ static int vmw_cmd_res_reloc_add(struct vmw_private *dev_priv, { int ret; - ret = vmw_resource_relocation_add(&sw_context->res_relocations, - res, + ret = vmw_resource_relocation_add(sw_context, res, vmw_ptr_diff(sw_context->buf_start, id_loc), vmw_res_rel_normal); @@ -597,7 +609,7 @@ vmw_cmd_res_check(struct vmw_private *dev_priv, *p_res = res; return vmw_resource_relocation_add - (&sw_context->res_relocations, res, + (sw_context, res, vmw_ptr_diff(sw_context->buf_start, id_loc), vmw_res_rel_normal); } @@ -1150,14 +1162,10 @@ static int vmw_translate_mob_ptr(struct vmw_private *dev_priv, goto out_no_reloc; } - if (unlikely(sw_context->cur_reloc >= VMWGFX_MAX_RELOCATIONS)) { - DRM_ERROR("Max number relocations per submission" - " exceeded\n"); - ret = -EINVAL; + reloc = vmw_validation_mem_alloc(sw_context->ctx, sizeof(*reloc)); + if (!reloc) goto out_no_reloc; - } - reloc = &sw_context->relocs[sw_context->cur_reloc++]; reloc->mob_loc = id; reloc->location = NULL; reloc->vbo = vmw_bo; @@ -1167,6 +1175,8 @@ static int vmw_translate_mob_ptr(struct vmw_private *dev_priv, goto out_no_reloc; *vmw_bo_p = vmw_bo; + list_add_tail(&reloc->head, &sw_context->bo_relocations); + return 0; out_no_reloc: @@ -1211,14 +1221,10 @@ static int vmw_translate_guest_ptr(struct vmw_private *dev_priv, goto out_no_reloc; } - if (unlikely(sw_context->cur_reloc >= VMWGFX_MAX_RELOCATIONS)) { - DRM_ERROR("Max number relocations per submission" - " exceeded\n"); - ret = -EINVAL; + reloc = vmw_validation_mem_alloc(sw_context->ctx, sizeof(*reloc)); + if (!reloc) goto out_no_reloc; - } - reloc = &sw_context->relocs[sw_context->cur_reloc++]; reloc->location = ptr; reloc->vbo = vmw_bo; @@ -1227,6 +1233,8 @@ static int vmw_translate_guest_ptr(struct vmw_private *dev_priv, goto out_no_reloc; *vmw_bo_p = vmw_bo; + list_add_tail(&reloc->head, &sw_context->bo_relocations); + return 0; out_no_reloc: @@ -2055,7 +2063,7 @@ static int vmw_cmd_shader_define(struct vmw_private *dev_priv, if (unlikely(ret != 0)) return ret; - return vmw_resource_relocation_add(&sw_context->res_relocations, + return vmw_resource_relocation_add(sw_context, NULL, vmw_ptr_diff(sw_context->buf_start, &cmd->header.id), @@ -2100,7 +2108,7 @@ static int vmw_cmd_shader_destroy(struct vmw_private *dev_priv, if (unlikely(ret != 0)) return ret; - return vmw_resource_relocation_add(&sw_context->res_relocations, + return vmw_resource_relocation_add(sw_context, NULL, vmw_ptr_diff(sw_context->buf_start, &cmd->header.id), @@ -2801,7 +2809,7 @@ static int vmw_cmd_dx_view_remove(struct vmw_private *dev_priv, * relocation to conditionally make this command a NOP to avoid * device errors. */ - return vmw_resource_relocation_add(&sw_context->res_relocations, + return vmw_resource_relocation_add(sw_context, view, vmw_ptr_diff(sw_context->buf_start, &cmd->header.id), @@ -3504,17 +3512,17 @@ static int vmw_cmd_check_all(struct vmw_private *dev_priv, static void vmw_free_relocations(struct vmw_sw_context *sw_context) { - sw_context->cur_reloc = 0; + /* Memory is validation context memory, so no need to free it */ + + INIT_LIST_HEAD(&sw_context->bo_relocations); } static void vmw_apply_relocations(struct vmw_sw_context *sw_context) { - uint32_t i; struct vmw_relocation *reloc; struct ttm_buffer_object *bo; - for (i = 0; i < sw_context->cur_reloc; ++i) { - reloc = &sw_context->relocs[i]; + list_for_each_entry(reloc, &sw_context->bo_relocations, head) { bo = &reloc->vbo->base; switch (bo->mem.mem_type) { case TTM_PL_VRAM: @@ -3914,7 +3922,6 @@ int vmw_execbuf_process(struct drm_file *file_priv, sw_context->kernel = true; sw_context->fp = vmw_fpriv(file_priv); - sw_context->cur_reloc = 0; INIT_LIST_HEAD(&sw_context->ctx_list); sw_context->cur_query_bo = dev_priv->pinned_bo; sw_context->last_query_ctx = NULL; @@ -3924,6 +3931,7 @@ int vmw_execbuf_process(struct drm_file *file_priv, sw_context->dx_query_ctx = NULL; memset(sw_context->res_cache, 0, sizeof(sw_context->res_cache)); INIT_LIST_HEAD(&sw_context->res_relocations); + INIT_LIST_HEAD(&sw_context->bo_relocations); if (sw_context->staged_bindings) vmw_binding_state_reset(sw_context->staged_bindings); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c index dbb58cce0987..3158fe161b2d 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c @@ -79,6 +79,66 @@ struct vmw_validation_res_node { unsigned long private[0]; }; +/** + * vmw_validation_mem_alloc - Allocate kernel memory from the validation + * context based allocator + * @ctx: The validation context + * @size: The number of bytes to allocated. + * + * The memory allocated may not exceed PAGE_SIZE, and the returned + * address is aligned to sizeof(long). All memory allocated this way is + * reclaimed after validation when calling any of the exported functions: + * vmw_validation_unref_lists() + * vmw_validation_revert() + * vmw_validation_done() + * + * Return: Pointer to the allocated memory on success. NULL on failure. + */ +void *vmw_validation_mem_alloc(struct vmw_validation_context *ctx, size_t size) +{ + void *addr; + + size = ALIGN(size, sizeof(long)); + if (size > PAGE_SIZE) + return NULL; + + if (ctx->mem_size_left < size) { + struct page *page = alloc_page(GFP_KERNEL | __GFP_ZERO); + + if (!page) + return NULL; + + list_add_tail(&page->lru, &ctx->page_list); + ctx->page_address = page_address(page); + ctx->mem_size_left = PAGE_SIZE; + } + + addr = (void *) (ctx->page_address + (PAGE_SIZE - ctx->mem_size_left)); + ctx->mem_size_left -= size; + + return addr; +} + +/** + * vmw_validation_mem_free - Free all memory allocated using + * vmw_validation_mem_alloc() + * @ctx: The validation context + * + * All memory previously allocated for this context using + * vmw_validation_mem_alloc() is freed. + */ +static void vmw_validation_mem_free(struct vmw_validation_context *ctx) +{ + struct page *entry, *next; + + list_for_each_entry_safe(entry, next, &ctx->page_list, lru) { + list_del_init(&entry->lru); + __free_page(entry); + } + + ctx->mem_size_left = 0; +} + /** * vmw_validation_find_bo_dup - Find a duplicate buffer object entry in the * validation context's lists. @@ -188,7 +248,7 @@ int vmw_validation_add_bo(struct vmw_validation_context *ctx, struct ttm_validate_buffer *val_buf; int ret; - bo_node = kmalloc(sizeof(*bo_node), GFP_KERNEL); + bo_node = vmw_validation_mem_alloc(ctx, sizeof(*bo_node)); if (!bo_node) return -ENOMEM; @@ -198,7 +258,6 @@ int vmw_validation_add_bo(struct vmw_validation_context *ctx, if (ret) { DRM_ERROR("Failed to initialize a buffer " "validation entry.\n"); - kfree(bo_node); return ret; } } @@ -238,7 +297,7 @@ int vmw_validation_add_resource(struct vmw_validation_context *ctx, goto out_fill; } - node = kzalloc(sizeof(*node) + priv_size, GFP_KERNEL); + node = vmw_validation_mem_alloc(ctx, sizeof(*node) + priv_size); if (!node) { DRM_ERROR("Failed to allocate a resource validation " "entry.\n"); @@ -251,7 +310,6 @@ int vmw_validation_add_resource(struct vmw_validation_context *ctx, if (ret) { DRM_ERROR("Failed to initialize a resource validation " "entry.\n"); - kfree(node); return ret; } } @@ -542,25 +600,24 @@ void vmw_validation_drop_ht(struct vmw_validation_context *ctx) */ void vmw_validation_unref_lists(struct vmw_validation_context *ctx) { - struct vmw_validation_bo_node *entry, *next; - struct vmw_validation_res_node *val, *val_next; + struct vmw_validation_bo_node *entry; + struct vmw_validation_res_node *val; - list_for_each_entry_safe(entry, next, &ctx->bo_list, base.head) { - list_del(&entry->base.head); + list_for_each_entry(entry, &ctx->bo_list, base.head) ttm_bo_unref(&entry->base.bo); - kfree(entry); - } list_splice_init(&ctx->resource_ctx_list, &ctx->resource_list); - list_for_each_entry_safe(val, val_next, &ctx->resource_list, head) { - list_del(&val->head); + list_for_each_entry(val, &ctx->resource_list, head) vmw_resource_unreference(&val->res); - kfree(val); - } - WARN_ON(!list_empty(&ctx->bo_list)); - WARN_ON(!list_empty(&ctx->resource_list)); - WARN_ON(!list_empty(&ctx->resource_ctx_list)); + /* + * No need to detach each list entry since they are all freed with + * vmw_validation_free_mem. Just make the inaccessible. + */ + INIT_LIST_HEAD(&ctx->bo_list); + INIT_LIST_HEAD(&ctx->resource_list); + + vmw_validation_mem_free(ctx); } /** @@ -637,6 +694,7 @@ void vmw_validation_revert(struct vmw_validation_context *ctx) vmw_validation_res_unreserve(ctx, true); if (ctx->res_mutex) mutex_unlock(ctx->res_mutex); + vmw_validation_unref_lists(ctx); } /** diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.h b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.h index 85f9387983a2..0eb2d02d0c0c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.h @@ -40,19 +40,25 @@ * @resource_ctx_list: List head for resource validation metadata for * resources that need to be validated before those in @resource_list * @bo_list: List head for buffer objects + * @page_list: List of pages used by the memory allocator * @ticket: Ticked used for ww mutex locking * @res_mutex: Pointer to mutex used for resource reserving * @merge_dups: Whether to merge metadata for duplicate resources or * buffer objects + * @mem_size_left: Free memory left in the last page in @page_list + * @page_address: Kernel virtual address of the last page in @page_list */ struct vmw_validation_context { struct drm_open_hash *ht; struct list_head resource_list; struct list_head resource_ctx_list; struct list_head bo_list; + struct list_head page_list; struct ww_acquire_ctx ticket; struct mutex *res_mutex; unsigned int merge_dups; + unsigned int mem_size_left; + u8 *page_address; }; struct vmw_buffer_object; @@ -76,8 +82,10 @@ struct vmw_fence_obj; .resource_list = LIST_HEAD_INIT((_name).resource_list), \ .resource_ctx_list = LIST_HEAD_INIT((_name).resource_ctx_list), \ .bo_list = LIST_HEAD_INIT((_name).bo_list), \ + .page_list = LIST_HEAD_INIT((_name).page_list), \ + .res_mutex = NULL, \ .merge_dups = _merge_dups, \ - .res_mutex = NULL \ + .mem_size_left = 0, \ } /** @@ -199,4 +207,6 @@ void vmw_validation_revert(struct vmw_validation_context *ctx); void vmw_validation_done(struct vmw_validation_context *ctx, struct vmw_fence_obj *fence); +void *vmw_validation_mem_alloc(struct vmw_validation_context *ctx, size_t size); + #endif