<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <p>Hi Amber,</p>
    <p>I understand that different processes can get the same FD. My
      statement about FD being unique is relative to one process.</p>
    <p>The main problem with the global client ID is, that it allows
      process A to change the event mask of process B just by specifying
      process B's client ID. That can lead to denial of service attacks
      where process A can cause events not to be delivered to B or can
      flood process B with frequent events that it's not prepared to
      handle.</p>
    <p>Therefore you must make the lookup of the client from the client
      ID not from a global list, but from a per-process list. That way
      process A can only change event masks of process A clients, and
      not those of any other process.</p>
    <p>But if the client list is process-specific, you can use the FD as
      a unique identifier of the client within the process, so you don't
      need a separate client ID.</p>
    <p>Regards,<br>
        Felix<br>
    </p>
    <div class="moz-cite-prefix">Am 2020-04-14 um 8:09 p.m. schrieb Lin,
      Amber:<br>
    </div>
    <blockquote type="cite" cite="mid:BN8PR12MB30418878CCC5D2FE5103248DE1DB0@BN8PR12MB3041.namprd12.prod.outlook.com">
      
      <meta name="Generator" content="Microsoft Word 15 (filtered
        medium)">
      <style><!--
/* Font Definitions */
@font-face
        {font-family:PMingLiU;
        panose-1:2 1 6 1 0 1 1 1 1 1;}
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Consolas;
        panose-1:2 11 6 9 2 2 4 3 2 4;}
@font-face
        {font-family:"\@PMingLiU";
        panose-1:2 1 6 1 0 1 1 1 1 1;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
pre
        {mso-style-priority:99;
        mso-style-link:"HTML Preformatted Char";
        margin:0in;
        margin-bottom:.0001pt;
        font-size:10.0pt;
        font-family:"Courier New";}
span.HTMLPreformattedChar
        {mso-style-name:"HTML Preformatted Char";
        mso-style-priority:99;
        mso-style-link:"HTML Preformatted";
        font-family:Consolas;}
p.msipheader4d0fcdd7, li.msipheader4d0fcdd7, div.msipheader4d0fcdd7
        {mso-style-name:msipheader4d0fcdd7;
        mso-margin-top-alt:auto;
        margin-right:0in;
        mso-margin-bottom-alt:auto;
        margin-left:0in;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
span.EmailStyle22
        {mso-style-type:personal-compose;
        font-family:"Arial",sans-serif;
        color:#0078D7;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
/* List Definitions */
@list l0
        {mso-list-id:711004651;
        mso-list-template-ids:506200590;}
@list l1
        {mso-list-id:841353468;
        mso-list-template-ids:-1447530186;}
@list l1:level1
        {mso-level-tab-stop:.5in;
        mso-level-number-position:left;
        text-indent:-.25in;}
@list l1:level2
        {mso-level-tab-stop:1.0in;
        mso-level-number-position:left;
        text-indent:-.25in;}
@list l1:level3
        {mso-level-tab-stop:1.5in;
        mso-level-number-position:left;
        text-indent:-.25in;}
@list l1:level4
        {mso-level-tab-stop:2.0in;
        mso-level-number-position:left;
        text-indent:-.25in;}
@list l1:level5
        {mso-level-tab-stop:2.5in;
        mso-level-number-position:left;
        text-indent:-.25in;}
@list l1:level6
        {mso-level-tab-stop:3.0in;
        mso-level-number-position:left;
        text-indent:-.25in;}
@list l1:level7
        {mso-level-tab-stop:3.5in;
        mso-level-number-position:left;
        text-indent:-.25in;}
@list l1:level8
        {mso-level-tab-stop:4.0in;
        mso-level-number-position:left;
        text-indent:-.25in;}
@list l1:level9
        {mso-level-tab-stop:4.5in;
        mso-level-number-position:left;
        text-indent:-.25in;}
ol
        {margin-bottom:0in;}
ul
        {margin-bottom:0in;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
      <div class="WordSection1">
        <p class="msipheader4d0fcdd7" style="margin:0in;margin-bottom:.0001pt"><span style="font-size:10.0pt;font-family:"Arial",sans-serif;color:#0078D7">[AMD
            Official Use Only - Internal Distribution Only]</span><o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">Hi Felix,<o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">That was my assumption too that each
          registration will get different file descriptor, but it turns
          out not. When I started two process and both register gpu0 and
          gpu1, they both got fd=15. If I have process A register
          gpu0+gpu1, and process B only register gpu0, process A gets
          fd=15 and process B gets fd=9. That’s why I added client ID.<o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">By multiple clients, I mean multiple
          processes. The ask is users want to have multiple tools and
          those different tools can use rsmi lib to watch events at the
          same time. Due to the reason above that two processes can
          actually get the same fd and I need to add client ID to
          distinguish the registration, I don’t see the point of
          limiting one registration per process unless I use pid to
          distinguish the client instead, which was in my consideration
          too when I was writing the code. But second thought is why
          adding this restriction when client ID can allow the tool to
          watch different events on different devices if they want to.
          Maybe client ID is a bad term and it misleads you. I should
          call it register ID.<o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <div>
          <p class="MsoNormal">Regards,<o:p></o:p></p>
          <p class="MsoNormal">Amber<o:p></o:p></p>
        </div>
        <p class="MsoNormal"><o:p> </o:p></p>
        <div>
          <div style="border:none;border-top:solid #E1E1E1
            1.0pt;padding:3.0pt 0in 0in 0in">
            <p class="MsoNormal"><b>From:</b> Kuehling, Felix
              <a class="moz-txt-link-rfc2396E" href="mailto:Felix.Kuehling@amd.com"><Felix.Kuehling@amd.com></a> <br>
              <b>Sent:</b> Tuesday, April 14, 2020 7:04 PM<br>
              <b>To:</b> Lin, Amber <a class="moz-txt-link-rfc2396E" href="mailto:Amber.Lin@amd.com"><Amber.Lin@amd.com></a>;
              <a class="moz-txt-link-abbreviated" href="mailto:amd-gfx@lists.freedesktop.org">amd-gfx@lists.freedesktop.org</a><br>
              <b>Subject:</b> Re: [PATCH v4] drm/amdkfd: Provide SMI
              events watch<o:p></o:p></p>
          </div>
        </div>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p>Hi Amber,<o:p></o:p></p>
        <p>Some general remarks about the multi-client support. You
          added a global client id that's separate from the file
          descriptor. That's problematic for two reasons:<o:p></o:p></p>
        <ol type="1" start="1">
          <li class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;mso-list:l1
            level1 lfo3">
            A process could change a different process' event mask<o:p></o:p></li>
          <li class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;mso-list:l1
            level1 lfo3">
            The FD should already be unique per process, no need to
            invent another ID<o:p></o:p></li>
        </ol>
        <p>If we want to allow one process to register for events
          multiple times (multiple FDs per process), then the list of
          clients should be per process. Each process should only be
          allowed to change the event masks of its own clients. The
          client could be identified by its FD. No need for another
          client ID.<o:p></o:p></p>
        <p>But you could also simplify it further by allowing only one
          event client per process. Then you don't need the client ID
          lookup at all. Just have a single event client in the
          kfd_process.<o:p></o:p></p>
        <p>Another approach would be to make enable/disable functions of
          the event FD, rather than the KFD FD ioctl. It could be an
          ioctl of the event FD, or even simpler, you could use the
          write file-operation to write an event mask (of arbitrary
          length if you want to enable growth in the future). That way
          everything would be neatly encapsulated in the event FD
          private data.<o:p></o:p></p>
        <p>Two more comments inline ...<o:p></o:p></p>
        <p><o:p> </o:p></p>
        <div>
          <p class="MsoNormal">Am 2020-04-14 um 5:30 p.m. schrieb Amber
            Lin:<o:p></o:p></p>
        </div>
        <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
          <pre>When the compute is malfunctioning or performance drops, the system admin<o:p></o:p></pre>
          <pre>will use SMI (System Management Interface) tool to monitor/diagnostic what<o:p></o:p></pre>
          <pre>went wrong. This patch provides an event watch interface for the user<o:p></o:p></pre>
          <pre>space to register devices and subscribe events they are interested. After<o:p></o:p></pre>
          <pre>registered, the user can use annoymous file descriptor's poll function<o:p></o:p></pre>
          <pre>with wait-time specified and wait for events to happen. Once an event<o:p></o:p></pre>
          <pre>happens, the user can use read() to retrieve information related to the<o:p></o:p></pre>
          <pre>event.<o:p></o:p></pre>
          <pre><o:p> </o:p></pre>
          <pre>VM fault event is done in this patch.<o:p></o:p></pre>
          <pre><o:p> </o:p></pre>
          <pre>v2: - remove UNREGISTER and add event ENABLE/DISABLE<o:p></o:p></pre>
          <pre>    - correct kfifo usage<o:p></o:p></pre>
          <pre>    - move event message API to kfd_ioctl.h<o:p></o:p></pre>
          <pre>v3: send the event msg in text than in binary<o:p></o:p></pre>
          <pre>v4: support multiple clients<o:p></o:p></pre>
          <pre><o:p> </o:p></pre>
          <pre>Signed-off-by: Amber Lin <a href="mailto:Amber.Lin@amd.com" moz-do-not-send="true"><Amber.Lin@amd.com></a><o:p></o:p></pre>
        </blockquote>
        <p>[snip]<o:p></o:p></p>
        <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
          <pre>diff --git a/include/uapi/linux/kfd_ioctl.h b/include/uapi/linux/kfd_ioctl.h<o:p></o:p></pre>
          <pre>index 4f66764..8146437 100644<o:p></o:p></pre>
          <pre>--- a/include/uapi/linux/kfd_ioctl.h<o:p></o:p></pre>
          <pre>+++ b/include/uapi/linux/kfd_ioctl.h<o:p></o:p></pre>
          <pre>@@ -442,6 +442,36 @@ struct kfd_ioctl_import_dmabuf_args {<o:p></o:p></pre>
          <pre>  __u32 dmabuf_fd;       /* to KFD */<o:p></o:p></pre>
          <pre> };<o:p></o:p></pre>
          <pre> <o:p></o:p></pre>
          <pre>+/*<o:p></o:p></pre>
          <pre>+ * KFD SMI(System Management Interface) events<o:p></o:p></pre>
          <pre>+ */<o:p></o:p></pre>
          <pre>+enum kfd_smi_events_op {<o:p></o:p></pre>
          <pre>+ KFD_SMI_EVENTS_REGISTER = 1,<o:p></o:p></pre>
          <pre>+ KFD_SMI_EVENTS_ENABLE,<o:p></o:p></pre>
          <pre>+ KFD_SMI_EVENTS_DISABLE<o:p></o:p></pre>
          <pre>+};<o:p></o:p></pre>
          <pre>+<o:p></o:p></pre>
          <pre>+/* Event type (defined by bitmask) */<o:p></o:p></pre>
          <pre>+#define KFD_SMI_EVENT_VMFAULT     0x0000000000000001<o:p></o:p></pre>
          <pre>+<o:p></o:p></pre>
          <pre>+struct kfd_ioctl_smi_events_args {<o:p></o:p></pre>
          <pre>+ __u32 op;              /* to KFD */<o:p></o:p></pre>
          <pre>+ __u64 events;          /* to KFD */<o:p></o:p></pre>
        </blockquote>
        <p>The binary layout of the ioctl args structure should be the
          same on 32/64-bit. That means the 64-bit members should be
          64-bit aligned. The best way to ensure this is to put all the
          64-bit members first.<o:p></o:p></p>
        <p class="MsoNormal" style="margin-bottom:12.0pt"><o:p> </o:p></p>
        <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
          <pre><o:p> </o:p></pre>
          <pre>+ __u64 gpuids_array_ptr;        /* to KFD */<o:p></o:p></pre>
          <pre>+ __u32 num_gpuids;      /* to KFD */<o:p></o:p></pre>
          <pre>+ __u32 anon_fd;         /* from KFD */<o:p></o:p></pre>
          <pre>+ __u32 client_id;       /* to/from KFD */<o:p></o:p></pre>
          <pre>+};<o:p></o:p></pre>
          <pre>+<o:p></o:p></pre>
          <pre>+/* 1. All messages must start with (hex)uint64_event(16) + space(1) +<o:p></o:p></pre>
          <pre>+ *    (hex)gpuid(8) + space(1) =  26 bytes<o:p></o:p></pre>
          <pre>+ * 2. VmFault msg = (hex)uint32_pid(8) + space(1) + task name(16) = 25<o:p></o:p></pre>
          <pre>+ *    When a new event msg uses more memory, change the calculation here.<o:p></o:p></pre>
          <pre>+ * 3. End with \n(1)<o:p></o:p></pre>
          <pre>+ * 26 + 25 + 1 = 52<o:p></o:p></pre>
          <pre>+ */<o:p></o:p></pre>
          <pre>+#define KFD_SMI_MAX_EVENT_MSG 52<o:p></o:p></pre>
        </blockquote>
        <p>If you define the maximum message length here, clients may
          start depending on it, and it gets harder to change it later.
          I'd not define this in the API header. It's not necessary to
          write correct clients. And if used badly, it may encourage
          writing incorrect clients that break with longer messages in
          the future.<o:p></o:p></p>
        <p>Regards,<br>
            Felix<o:p></o:p></p>
        <p><o:p> </o:p></p>
        <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
          <pre><o:p> </o:p></pre>
          <pre>+<o:p></o:p></pre>
          <pre> /* Register offset inside the remapped mmio page<o:p></o:p></pre>
          <pre>  */<o:p></o:p></pre>
          <pre> enum kfd_mmio_remap {<o:p></o:p></pre>
          <pre>@@ -546,7 +576,10 @@ enum kfd_mmio_remap {<o:p></o:p></pre>
          <pre> #define AMDKFD_IOC_ALLOC_QUEUE_GWS            \<o:p></o:p></pre>
          <pre>         AMDKFD_IOWR(0x1E, struct kfd_ioctl_alloc_queue_gws_args)<o:p></o:p></pre>
          <pre> <o:p></o:p></pre>
          <pre>+#define AMDKFD_IOC_SMI_EVENTS                 \<o:p></o:p></pre>
          <pre>+        AMDKFD_IOWR(0x1F, struct kfd_ioctl_smi_events_args)<o:p></o:p></pre>
          <pre>+<o:p></o:p></pre>
          <pre> #define AMDKFD_COMMAND_START           0x01<o:p></o:p></pre>
          <pre>-#define AMDKFD_COMMAND_END             0x1F<o:p></o:p></pre>
          <pre>+#define AMDKFD_COMMAND_END             0x20<o:p></o:p></pre>
          <pre> <o:p></o:p></pre>
          <pre> #endif<o:p></o:p></pre>
        </blockquote>
      </div>
    </blockquote>
  </body>
</html>