Message ID | 20230621005719.836857-1-andrealmeid@igalia.com |
---|---|
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp4067706vqr; Tue, 20 Jun 2023 19:09:10 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ7FD4yEi3ZAqk0F8AUJutZzHFqjzfK7Bnv87leRNisDP/h0mrwNG9AuJ9FQiPVzf2zHtwyA X-Received: by 2002:a05:6a00:b8f:b0:666:5fc4:36b1 with SMTP id g15-20020a056a000b8f00b006665fc436b1mr11439575pfj.26.1687313349810; Tue, 20 Jun 2023 19:09:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1687313349; cv=none; d=google.com; s=arc-20160816; b=D8N8pENSnDd9CT5LtIyclIkQjGsH2LJTLNsCH+/X8a7iKxDsm21qprVoG/upxIOoEI jElXQz43D2kCfRFhUNWHazrUzojbhw9Ik6SAj0tkF6XTcDjXHhgYggqxIXYoBmAaLayJ H51PmVJeqkm1PnQTTGq+8Rh1Fgut7WUzS4BchZ929qXy2XNuEYxF038heq3fLGE8SOzo HNhJ8IbGLb0CxpkIBsLDSqkIgWtcP+3JfQnR6iqjs7R9p8iQrfm9ozW+KFTvP3sFbedY GV+Tore494P+RJdYe2aWtDMqLu/R7CWqucwyCS+HKTAhZlkihVMwx2xJQA14ZXKv51iC Hr6A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=dD+0WX2WV6Iq8HXq3xOanwTmTky971Axctsxt30metE=; b=NZnq+BqGUG+fEMN1LSR4UjvdCynQwHg6XyKhd4R8vfdjW090xxeKhjrzMFGdf13TGx SCXbybH9+T8M4rRzMxxiTmkHEBAmxRjSI0De8UTPqtnJ3c3tZOVnZ+/JTCHFDLdRzlfT 5F3ITnJaiKeUW/SHRseTII0ODYiMHUDypbvrKh4PSXMV8rKSyb57SqOint/kOniKyzf9 7kp1y6l+vx8ZhioC5R2ZC1orZjHgP3QO25p662fm25wDDgE5SiltWTtc/+OZLSiD3mfL dVXtILgZ3bWXxvlNqnT1M2m1r9i+lzpdV3gfTd5uq6TAC5aNIegMrNkiYbdrSjzcqNq/ bimA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@igalia.com header.s=20170329 header.b=AFwHoupW; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id p2-20020aa79e82000000b00668873710d9si3050795pfq.162.2023.06.20.19.08.55; Tue, 20 Jun 2023 19:09:09 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=fail header.i=@igalia.com header.s=20170329 header.b=AFwHoupW; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229913AbjFUA6f (ORCPT <rfc822;maxin.john@gmail.com> + 99 others); Tue, 20 Jun 2023 20:58:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53668 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229527AbjFUA6d (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Tue, 20 Jun 2023 20:58:33 -0400 Received: from fanzine2.igalia.com (fanzine2.igalia.com [213.97.179.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 03D22183 for <linux-kernel@vger.kernel.org>; Tue, 20 Jun 2023 17:58:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:Content-Type:MIME-Version:Message-ID: Date:Subject:Cc:To:From:Sender:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=dD+0WX2WV6Iq8HXq3xOanwTmTky971Axctsxt30metE=; b=AFwHoupWdW4Ozmxjp9xj9e/m3t XZc6hhXZuz5Fqn+LWY/W1l4/QQ1VyrBkr7VIpCSaHzXE/fdAdnp/75Dn1rn5uAi2Bgg217t9kJ2DL DOrVgClp6/5GFX7rbSDkZM5ISxzBF0vSDfhAYDUAX0Pt3oRkdJ24nXyARDkobAwV6t39Qck2p+Vlv dVgec97mwUL9tjx6bfBs2i4X+Wimp+yavP138mdogQBNrjjVDKlLy1xgaoFbmzZCBfuZD3MmA75qY qBhPdsjj40Yf424y7WVChuNJGMavYTZxlcMpdSp5ieY3WCGOzLFVpsv6BzWR+5Jqqq/F9CARcy+kS Pdb6XNGw==; Received: from [179.113.218.86] (helo=steammachine.lan) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1qBmAz-0011pg-Iu; Wed, 21 Jun 2023 02:58:26 +0200 From: =?utf-8?q?Andr=C3=A9_Almeida?= <andrealmeid@igalia.com> To: dri-devel@lists.freedesktop.org, amd-gfx@lists.freedesktop.org, linux-kernel@vger.kernel.org Cc: kernel-dev@igalia.com, alexander.deucher@amd.com, christian.koenig@amd.com, pierre-eric.pelloux-prayer@amd.com, Simon Ser <contact@emersion.fr>, Rob Clark <robdclark@gmail.com>, Pekka Paalanen <ppaalanen@gmail.com>, Daniel Vetter <daniel@ffwll.ch>, Daniel Stone <daniel@fooishbar.org>, =?utf-8?b?J01hcmVrIE9sxaHDoWsn?= <maraeo@gmail.com>, Dave Airlie <airlied@gmail.com>, =?utf-8?q?Michel_D=C3=A4nzer?= <michel.daenzer@mailbox.org>, Samuel Pitoiset <samuel.pitoiset@gmail.com>, =?utf-8?q?Timur_Krist=C3=B3f?= <timur.kristof@gmail.com>, Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>, =?utf-8?q?Andr=C3=A9_Almeida?= <andrealmeid@igalia.com> Subject: [RFC PATCH v3 0/4] drm: Standardize device reset notification Date: Tue, 20 Jun 2023 21:57:15 -0300 Message-ID: <20230621005719.836857-1-andrealmeid@igalia.com> X-Mailer: git-send-email 2.41.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED autolearn=ham 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: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1769276282980062469?= X-GMAIL-MSGID: =?utf-8?q?1769276282980062469?= |
Series |
drm: Standardize device reset notification
|
|
Message
André Almeida
June 21, 2023, 12:57 a.m. UTC
Hi, This is a new version of the documentation for DRM device resets. As I dived more in the subject, I started to believe that part of the problem was the lack of a DRM API to get reset information from the driver. With an API, we can better standardize reset queries, increase common code from both DRM and Mesa, and make easier to write end-to-end tests. So this patchset, along with the documentation, comes with a new IOCTL and two implementations of it for amdgpu and i915 (although just the former was really tested). This IOCTL uses the "context id" to query reset information, but this might be not generic enough to be included in a DRM API. At least for amdgpu, this information is encapsulated by libdrm so one can't just call the ioctl directly from the UMD as I was planning to, but a small refactor can be done to expose the id. Anyway, I'm sharing it as it is to gather feedback if this seems to work. The amdgpu and i915 implementations are provided as a mean of testing and as exemplification, and not as reference code yet, as the goal is more about the interface itself then the driver parts. For the documentation itself, after spending some time reading the reset path in the kernel in Mesa, I decide to rewrite it to better reflect how it works, from bottom to top. You can check the userspace side of the IOCLT here: Mesa: https://gitlab.freedesktop.org/andrealmeid/mesa/-/commit/cd687b22fb32c21b23596c607003e2a495f465 libdrm: https://gitlab.freedesktop.org/andrealmeid/libdrm/-/commit/b31e5404893ee9a85d1aa67e81c2f58c1dac3c46 For testing, I use this vulkan app that has an infinity loop in the shader: https://github.com/andrealmeid/vulkan-triangle-v1 Feedbacks are welcomed! Thanks, André v2: https://lore.kernel.org/all/20230227204000.56787-1-andrealmeid@igalia.com/ v1: https://lore.kernel.org/all/20230123202646.356592-1-andrealmeid@igalia.com/ André Almeida (4): drm/doc: Document DRM device reset expectations drm: Create DRM_IOCTL_GET_RESET drm/amdgpu: Implement DRM_IOCTL_GET_RESET drm/i915: Implement DRM_IOCTL_GET_RESET Documentation/gpu/drm-uapi.rst | 51 ++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 4 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 35 +++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h | 5 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 12 +++- drivers/gpu/drm/amd/amdgpu/amdgpu_job.h | 2 + drivers/gpu/drm/drm_debugfs.c | 2 + drivers/gpu/drm/drm_ioctl.c | 58 +++++++++++++++++++ drivers/gpu/drm/i915/gem/i915_gem_context.c | 18 ++++++ drivers/gpu/drm/i915/gem/i915_gem_context.h | 2 + .../gpu/drm/i915/gem/i915_gem_context_types.h | 2 + drivers/gpu/drm/i915/i915_driver.c | 2 + include/drm/drm_device.h | 3 + include/drm/drm_drv.h | 3 + include/uapi/drm/drm.h | 21 +++++++ include/uapi/drm/drm_mode.h | 15 +++++ 17 files changed, 233 insertions(+), 3 deletions(-)
Comments
Am 21.06.23 um 02:57 schrieb André Almeida: > Hi, > > This is a new version of the documentation for DRM device resets. As I dived > more in the subject, I started to believe that part of the problem was the lack > of a DRM API to get reset information from the driver. With an API, we can > better standardize reset queries, increase common code from both DRM and Mesa, > and make easier to write end-to-end tests. > > So this patchset, along with the documentation, comes with a new IOCTL and two > implementations of it for amdgpu and i915 (although just the former was really > tested). This IOCTL uses the "context id" to query reset information, but this > might be not generic enough to be included in a DRM API. Well the basic problem with that is that we don't have a standard DRM context defined. If you want to do this you should probably start there first. Apart from that this looks like a really really good idea to me, especially that we document the reset expectations. Regards, Christian. > At least for amdgpu, > this information is encapsulated by libdrm so one can't just call the ioctl > directly from the UMD as I was planning to, but a small refactor can be done to > expose the id. Anyway, I'm sharing it as it is to gather feedback if this seems > to work. > > The amdgpu and i915 implementations are provided as a mean of testing and as > exemplification, and not as reference code yet, as the goal is more about the > interface itself then the driver parts. > > For the documentation itself, after spending some time reading the reset path in > the kernel in Mesa, I decide to rewrite it to better reflect how it works, from > bottom to top. > > You can check the userspace side of the IOCLT here: > Mesa: https://gitlab.freedesktop.org/andrealmeid/mesa/-/commit/cd687b22fb32c21b23596c607003e2a495f465 > libdrm: https://gitlab.freedesktop.org/andrealmeid/libdrm/-/commit/b31e5404893ee9a85d1aa67e81c2f58c1dac3c46 > > For testing, I use this vulkan app that has an infinity loop in the shader: > https://github.com/andrealmeid/vulkan-triangle-v1 > > Feedbacks are welcomed! > > Thanks, > André > > v2: https://lore.kernel.org/all/20230227204000.56787-1-andrealmeid@igalia.com/ > v1: https://lore.kernel.org/all/20230123202646.356592-1-andrealmeid@igalia.com/ > > André Almeida (4): > drm/doc: Document DRM device reset expectations > drm: Create DRM_IOCTL_GET_RESET > drm/amdgpu: Implement DRM_IOCTL_GET_RESET > drm/i915: Implement DRM_IOCTL_GET_RESET > > Documentation/gpu/drm-uapi.rst | 51 ++++++++++++++++ > drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 4 +- > drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 35 +++++++++++ > drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h | 5 ++ > drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 1 + > drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 12 +++- > drivers/gpu/drm/amd/amdgpu/amdgpu_job.h | 2 + > drivers/gpu/drm/drm_debugfs.c | 2 + > drivers/gpu/drm/drm_ioctl.c | 58 +++++++++++++++++++ > drivers/gpu/drm/i915/gem/i915_gem_context.c | 18 ++++++ > drivers/gpu/drm/i915/gem/i915_gem_context.h | 2 + > .../gpu/drm/i915/gem/i915_gem_context_types.h | 2 + > drivers/gpu/drm/i915/i915_driver.c | 2 + > include/drm/drm_device.h | 3 + > include/drm/drm_drv.h | 3 + > include/uapi/drm/drm.h | 21 +++++++ > include/uapi/drm/drm_mode.h | 15 +++++ > 17 files changed, 233 insertions(+), 3 deletions(-) >
Em 21/06/2023 04:42, Christian König escreveu: > Am 21.06.23 um 02:57 schrieb André Almeida: >> Hi, >> >> This is a new version of the documentation for DRM device resets. As I >> dived >> more in the subject, I started to believe that part of the problem was >> the lack >> of a DRM API to get reset information from the driver. With an API, we >> can >> better standardize reset queries, increase common code from both DRM >> and Mesa, >> and make easier to write end-to-end tests. >> >> So this patchset, along with the documentation, comes with a new IOCTL >> and two >> implementations of it for amdgpu and i915 (although just the former >> was really >> tested). This IOCTL uses the "context id" to query reset information, >> but this >> might be not generic enough to be included in a DRM API. > > Well the basic problem with that is that we don't have a standard DRM > context defined. > > If you want to do this you should probably start there first. Any idea on how to start this? I tried to find previous work about that, but I didn't find. > > Apart from that this looks like a really really good idea to me, > especially that we document the reset expectations. I think I'll submit just the doc for the next version then, given that the IOCTL will need a lot of rework. > > Regards, > Christian. > >> At least for amdgpu, >> this information is encapsulated by libdrm so one can't just call the >> ioctl >> directly from the UMD as I was planning to, but a small refactor can >> be done to >> expose the id. Anyway, I'm sharing it as it is to gather feedback if >> this seems >> to work. >> >> The amdgpu and i915 implementations are provided as a mean of testing >> and as >> exemplification, and not as reference code yet, as the goal is more >> about the >> interface itself then the driver parts. >> >> For the documentation itself, after spending some time reading the >> reset path in >> the kernel in Mesa, I decide to rewrite it to better reflect how it >> works, from >> bottom to top. >> >> You can check the userspace side of the IOCLT here: >> Mesa: >> https://gitlab.freedesktop.org/andrealmeid/mesa/-/commit/cd687b22fb32c21b23596c607003e2a495f465 >> libdrm: >> https://gitlab.freedesktop.org/andrealmeid/libdrm/-/commit/b31e5404893ee9a85d1aa67e81c2f58c1dac3c46 >> >> For testing, I use this vulkan app that has an infinity loop in the >> shader: >> https://github.com/andrealmeid/vulkan-triangle-v1 >> >> Feedbacks are welcomed! >> >> Thanks, >> André >> >> v2: >> https://lore.kernel.org/all/20230227204000.56787-1-andrealmeid@igalia.com/ >> v1: >> https://lore.kernel.org/all/20230123202646.356592-1-andrealmeid@igalia.com/ >> >> André Almeida (4): >> drm/doc: Document DRM device reset expectations >> drm: Create DRM_IOCTL_GET_RESET >> drm/amdgpu: Implement DRM_IOCTL_GET_RESET >> drm/i915: Implement DRM_IOCTL_GET_RESET >> >> Documentation/gpu/drm-uapi.rst | 51 ++++++++++++++++ >> drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 4 +- >> drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 35 +++++++++++ >> drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h | 5 ++ >> drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 1 + >> drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 12 +++- >> drivers/gpu/drm/amd/amdgpu/amdgpu_job.h | 2 + >> drivers/gpu/drm/drm_debugfs.c | 2 + >> drivers/gpu/drm/drm_ioctl.c | 58 +++++++++++++++++++ >> drivers/gpu/drm/i915/gem/i915_gem_context.c | 18 ++++++ >> drivers/gpu/drm/i915/gem/i915_gem_context.h | 2 + >> .../gpu/drm/i915/gem/i915_gem_context_types.h | 2 + >> drivers/gpu/drm/i915/i915_driver.c | 2 + >> include/drm/drm_device.h | 3 + >> include/drm/drm_drv.h | 3 + >> include/uapi/drm/drm.h | 21 +++++++ >> include/uapi/drm/drm_mode.h | 15 +++++ >> 17 files changed, 233 insertions(+), 3 deletions(-) >> >
Am 21.06.23 um 17:06 schrieb André Almeida: > Em 21/06/2023 04:42, Christian König escreveu: >> Am 21.06.23 um 02:57 schrieb André Almeida: >>> Hi, >>> >>> This is a new version of the documentation for DRM device resets. As >>> I dived >>> more in the subject, I started to believe that part of the problem >>> was the lack >>> of a DRM API to get reset information from the driver. With an API, >>> we can >>> better standardize reset queries, increase common code from both DRM >>> and Mesa, >>> and make easier to write end-to-end tests. >>> >>> So this patchset, along with the documentation, comes with a new >>> IOCTL and two >>> implementations of it for amdgpu and i915 (although just the former >>> was really >>> tested). This IOCTL uses the "context id" to query reset >>> information, but this >>> might be not generic enough to be included in a DRM API. >> >> Well the basic problem with that is that we don't have a standard DRM >> context defined. >> >> If you want to do this you should probably start there first. > > Any idea on how to start this? I tried to find previous work about > that, but I didn't find. I'm not aware of any work in this area, maybe ping on the Mesa list as well. Could be that someone looked into that but never send anything out. > >> >> Apart from that this looks like a really really good idea to me, >> especially that we document the reset expectations. > > I think I'll submit just the doc for the next version then, given that > the IOCTL will need a lot of rework. Yeah, agree completely. Thanks, Christian. > >> >> Regards, >> Christian. >> >>> At least for amdgpu, >>> this information is encapsulated by libdrm so one can't just call >>> the ioctl >>> directly from the UMD as I was planning to, but a small refactor can >>> be done to >>> expose the id. Anyway, I'm sharing it as it is to gather feedback if >>> this seems >>> to work. >>> >>> The amdgpu and i915 implementations are provided as a mean of >>> testing and as >>> exemplification, and not as reference code yet, as the goal is more >>> about the >>> interface itself then the driver parts. >>> >>> For the documentation itself, after spending some time reading the >>> reset path in >>> the kernel in Mesa, I decide to rewrite it to better reflect how it >>> works, from >>> bottom to top. >>> >>> You can check the userspace side of the IOCLT here: >>> Mesa: >>> https://gitlab.freedesktop.org/andrealmeid/mesa/-/commit/cd687b22fb32c21b23596c607003e2a495f465 >>> libdrm: >>> https://gitlab.freedesktop.org/andrealmeid/libdrm/-/commit/b31e5404893ee9a85d1aa67e81c2f58c1dac3c46 >>> >>> For testing, I use this vulkan app that has an infinity loop in the >>> shader: >>> https://github.com/andrealmeid/vulkan-triangle-v1 >>> >>> Feedbacks are welcomed! >>> >>> Thanks, >>> André >>> >>> v2: >>> https://lore.kernel.org/all/20230227204000.56787-1-andrealmeid@igalia.com/ >>> v1: >>> https://lore.kernel.org/all/20230123202646.356592-1-andrealmeid@igalia.com/ >>> >>> André Almeida (4): >>> drm/doc: Document DRM device reset expectations >>> drm: Create DRM_IOCTL_GET_RESET >>> drm/amdgpu: Implement DRM_IOCTL_GET_RESET >>> drm/i915: Implement DRM_IOCTL_GET_RESET >>> >>> Documentation/gpu/drm-uapi.rst | 51 ++++++++++++++++ >>> drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 4 +- >>> drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 35 +++++++++++ >>> drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h | 5 ++ >>> drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 1 + >>> drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 12 +++- >>> drivers/gpu/drm/amd/amdgpu/amdgpu_job.h | 2 + >>> drivers/gpu/drm/drm_debugfs.c | 2 + >>> drivers/gpu/drm/drm_ioctl.c | 58 >>> +++++++++++++++++++ >>> drivers/gpu/drm/i915/gem/i915_gem_context.c | 18 ++++++ >>> drivers/gpu/drm/i915/gem/i915_gem_context.h | 2 + >>> .../gpu/drm/i915/gem/i915_gem_context_types.h | 2 + >>> drivers/gpu/drm/i915/i915_driver.c | 2 + >>> include/drm/drm_device.h | 3 + >>> include/drm/drm_drv.h | 3 + >>> include/uapi/drm/drm.h | 21 +++++++ >>> include/uapi/drm/drm_mode.h | 15 +++++ >>> 17 files changed, 233 insertions(+), 3 deletions(-) >>> >>