<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <div class="moz-cite-prefix">On 12/12/2024 16:32, Lucas De Marchi
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:zy2x47cknwhzycszh7otjn5t65pvsotwwftcbleq44cmzbibaw@5gsx7zp7t2sm">On
      Thu, Dec 12, 2024 at 01:04:23PM -0800, John Harrison wrote:
      <br>
      <blockquote type="cite">On 12/12/2024 12:52, Lucas De Marchi
        wrote:
        <br>
        <blockquote type="cite">On Thu, Dec 12, 2024 at 11:14:23AM
          -0800, John Harrison wrote:
          <br>
          <blockquote type="cite">On 12/12/2024 10:45, Lucas De Marchi
            wrote:
            <br>
            <blockquote type="cite">On Thu, Dec 12, 2024 at 05:41:41PM
              +0000, Jose Souza wrote:
              <br>
              <blockquote type="cite">On Wed, 2024-10-02 at 17:46 -0700,
                <a class="moz-txt-link-abbreviated" href="mailto:John.C.Harrison@Intel.com">John.C.Harrison@Intel.com</a> wrote:
                <br>
                <blockquote type="cite">From: John Harrison
                  <a class="moz-txt-link-rfc2396E" href="mailto:John.C.Harrison@Intel.com"><John.C.Harrison@Intel.com></a>
                  <br>
                  <br>
                  There is a need to include the GuC log and other large
                  binary objects
                  <br>
                  in core dumps and via dmesg. So add a helper for
                  dumping to a printer
                  <br>
                  function via conversion to ASCII85 encoding.
                  <br>
                  <br>
                  Another issue with dumping such a large buffer is that
                  it can be slow,
                  <br>
                  especially if dumping to dmesg over a serial port. So
                  add a yield to
                  <br>
                  prevent the 'task has been stuck for 120s' kernel hang
                  check feature
                  <br>
                  from firing.
                  <br>
                  <br>
                  v2: Add a prefix to the output string. Fix memory
                  allocation bug.
                  <br>
                  v3: Correct a string size calculation and clean up a
                  define (review
                  <br>
                  feedback from Julia F).
                  <br>
                  <br>
                  Signed-off-by: John Harrison
                  <a class="moz-txt-link-rfc2396E" href="mailto:John.C.Harrison@Intel.com"><John.C.Harrison@Intel.com></a>
                  <br>
                  Reviewed-by: Julia Filipchuk
                  <a class="moz-txt-link-rfc2396E" href="mailto:julia.filipchuk@intel.com"><julia.filipchuk@intel.com></a>
                  <br>
                  ---
                  <br>
                   drivers/gpu/drm/xe/xe_devcoredump.c | 87
                  +++++++++++++++++++++++++++++
                  <br>
                   drivers/gpu/drm/xe/xe_devcoredump.h |  6 ++
                  <br>
                   2 files changed, 93 insertions(+)
                  <br>
                  <br>
                  diff --git a/drivers/gpu/drm/xe/xe_devcoredump.c
                  b/drivers/gpu/drm/xe/xe_devcoredump.c
                  <br>
                  index 2690f1d1cde4..0884c49942fe 100644
                  <br>
                  --- a/drivers/gpu/drm/xe/xe_devcoredump.c
                  <br>
                  +++ b/drivers/gpu/drm/xe/xe_devcoredump.c
                  <br>
                  @@ -6,6 +6,7 @@
                  <br>
                   #include "xe_devcoredump.h"
                  <br>
                   #include "xe_devcoredump_types.h"
                  <br>
                  <br>
                  +#include <linux/ascii85.h>
                  <br>
                   #include <linux/devcoredump.h>
                  <br>
                   #include <generated/utsrelease.h>
                  <br>
                  <br>
                  @@ -315,3 +316,89 @@ int xe_devcoredump_init(struct
                  xe_device *xe)
                  <br>
                   }
                  <br>
                  <br>
                   #endif
                  <br>
                  +
                  <br>
                  +/**
                  <br>
                  + * xe_print_blob_ascii85 - print a BLOB to some
                  useful location in ASCII85
                  <br>
                  + *
                  <br>
                  + * The output is split to multiple lines because some
                  print targets, e.g. dmesg
                  <br>
                  + * cannot handle arbitrarily long lines. Note also
                  that printing to dmesg in
                  <br>
                  + * piece-meal fashion is not possible, each separate
                  call to drm_puts() has a
                  <br>
                  + * line-feed automatically added! Therefore, the
                  entire output line must be
                  <br>
                  + * constructed in a local buffer first, then printed
                  in one atomic output call.
                  <br>
                  + *
                  <br>
                  + * There is also a scheduler yield call to prevent
                  the 'task has been stuck for
                  <br>
                  + * 120s' kernel hang check feature from firing when
                  printing to a slow target
                  <br>
                  + * such as dmesg over a serial port.
                  <br>
                  + *
                  <br>
                  + * TODO: Add compression prior to the ASCII85
                  encoding to shrink huge buffers down.
                  <br>
                  + *
                  <br>
                  + * @p: the printer object to output to
                  <br>
                  + * @prefix: optional prefix to add to output string
                  <br>
                  + * @blob: the Binary Large OBject to dump out
                  <br>
                  + * @offset: offset in bytes to skip from the front of
                  the BLOB, must be a multiple of sizeof(u32)
                  <br>
                  + * @size: the size in bytes of the BLOB, must be a
                  multiple of sizeof(u32)
                  <br>
                  + */
                  <br>
                  +void xe_print_blob_ascii85(struct drm_printer *p,
                  const char *prefix,
                  <br>
                  +               const void *blob, size_t offset,
                  size_t size)
                  <br>
                  +{
                  <br>
                  +    const u32 *blob32 = (const u32 *)blob;
                  <br>
                  +    char buff[ASCII85_BUFSZ], *line_buff;
                  <br>
                  +    size_t line_pos = 0;
                  <br>
                  +
                  <br>
                  +#define DMESG_MAX_LINE_LEN    800
                  <br>
                  +#define MIN_SPACE        (ASCII85_BUFSZ + 2)       
                  /* 85 + "\n\0" */
                  <br>
                  +
                  <br>
                  +    if (size & 3)
                  <br>
                  +        drm_printf(p, "Size not word aligned: %zu",
                  size);
                  <br>
                  +    if (offset & 3)
                  <br>
                  +        drm_printf(p, "Offset not word aligned: %zu",
                  size);
                  <br>
                  +
                  <br>
                  +    line_buff = kzalloc(DMESG_MAX_LINE_LEN,
                  GFP_KERNEL);
                  <br>
                  +    if (IS_ERR_OR_NULL(line_buff)) {
                  <br>
                  +        drm_printf(p, "Failed to allocate line
                  buffer: %pe", line_buff);
                  <br>
                  +        return;
                  <br>
                  +    }
                  <br>
                  +
                  <br>
                  +    blob32 += offset / sizeof(*blob32);
                  <br>
                  +    size /= sizeof(*blob32);
                  <br>
                  +
                  <br>
                  +    if (prefix) {
                  <br>
                  +        strscpy(line_buff, prefix, DMESG_MAX_LINE_LEN
                  - MIN_SPACE - 2);
                  <br>
                  +        line_pos = strlen(line_buff);
                  <br>
                  +
                  <br>
                  +        line_buff[line_pos++] = ':';
                  <br>
                  +        line_buff[line_pos++] = ' ';
                  <br>
                  +    }
                  <br>
                  +
                  <br>
                  +    while (size--) {
                  <br>
                  +        u32 val = *(blob32++);
                  <br>
                  +
                  <br>
                  +        strscpy(line_buff + line_pos,
                  ascii85_encode(val, buff),
                  <br>
                  +            DMESG_MAX_LINE_LEN - line_pos);
                  <br>
                  +        line_pos += strlen(line_buff + line_pos);
                  <br>
                  +
                  <br>
                  +        if ((line_pos + MIN_SPACE) >=
                  DMESG_MAX_LINE_LEN) {
                  <br>
                  +            line_buff[line_pos++] = '\n';
                  <br>
                  +            line_buff[line_pos++] = 0;
                  <br>
                </blockquote>
                <br>
                This breaks ascii85 parser that we had up to now.
                <br>
              </blockquote>
            </blockquote>
            It should not break the decoding of existing sections. This
            helper is only being used for the new GuC objects at
            present. As per the TODO, the intent is to use it for all
            blobs in the future. But that was deliberately left to a
            future update (which hasn't been posted yet) to avoid
            breaking the mesa tool.
            <br>
          </blockquote>
          <br>
          it broke nonetheless because then it fails to decode this line
          the way
          <br>
          it was doing:  each line starts a new key.
          <br>
        </blockquote>
        It barfs on any line it doesn't understand? Seems like it could
        be made to be more robust in general.
        <br>
      </blockquote>
      <br>
      I don't know, you're welcome to look at the source and understand
      how
      <br>
      it may possibly break when you are doing a change like that. Even
      better
      <br>
      if you can make it robust so it doesn't break. I'm sure you know
      where
      <br>
      the mesa repo is. I was just looking at what I wrote in the email
      thread
      <br>
      I pointed out when reviewing this. I was surprised it got applied
      as is,
      <br>
      knowing it would break (because I had pointed it out) even with 2
      <br>
      maintainers saying we shouldn't break the mesa tool in question...</blockquote>
    To be clear, no-one *knew* anything would break. The vast majority
    of that email thread was about whether we should include any ASCII85
    data in the devcoredump at all (which is something we had already
    been doing for a long time). What you actually wrote was:<br>
    <pre id="b" style="font-size: 13px; font-family: monospace; background: rgb(0, 0, 0); color: rgb(204, 204, 204); white-space: pre-wrap; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">+José, would it be ok from the userspace POV to start adding the \n?
Then we can at least have all fields in our devcoredump to follow the
same format. Are these the decoder parts on the mesa side?</pre>
    <br>
    Which to me reads as a question about whether we can update the
    existing ASCII85 sections to use the new helper function. It was not
    a question about whether adding a totally new field (using the new
    helper function) would cause a break. And given that there was no
    response after several weeks, it was reasonable to assume that it
    was not considered a problem.<br>
    <br>
    And there was never any discussion about whether adding extra
    section headings would cause a problem. That was never even
    considered to be 'unsafe'.<br>
    <br>
    John.<br>
    <br>
    <blockquote type="cite" cite="mid:zy2x47cknwhzycszh7otjn5t65pvsotwwftcbleq44cmzbibaw@5gsx7zp7t2sm">
      <br>
      particuarly it being just to please something that shouldn't exist
      (a
      <br>
      garbage dump to dmesg).
      <br>
      <br>
      And before you argue about format version and potential breakages
      if an
      <br>
      hypothetical parser is doing obscure things... this is different
      than
      <br>
      real breakage: we know there's a parser and we ignored it saying
      we
      <br>
      don't care. That is not acceptable.
      <br>
      <br>
      <blockquote type="cite">
        <br>
        <blockquote type="cite">
          <br>
          <blockquote type="cite">
            <br>
            <br>
            <blockquote type="cite">
              <blockquote type="cite">And I think there is not safe way
                to parse it now, how would the parser know that the blob
                reach to end?
                <br>
              </blockquote>
            </blockquote>
            The GuC decoder tool simply ignores leading/trailing
            whitespace and keeps decoding until it finds a line with a
            new field - i.e. anything with a non-ASCII85 character such
            as ':' or '*'. It is totally
            <br>
          </blockquote>
          <br>
          character set for ascii85 is [33, 117] and 122, which includes
          both ':'
          <br>
          and '*'. Hopefully it's hard to hit a collision, but we
          shouldn't design
          <br>
          it in a way that is possible.
          <br>
        </blockquote>
        Sorry, getting myself confused - it was a while ago when I was
        writing this. Yes, punctuation marks are part of the ASCII85
        character set.
        <br>
        <br>
        The GuC decoder looks for white space - a blank line or a line
        with a space in it. Any new field is guaranteed to be "name:
        data" so will have a space. And sections are delimited with
        blank lines, plus section headers are "**** name ****" so also
        guaranteed to have a space.
        <br>
      </blockquote>
      <br>
      space is good because it's outside the character set, so an
      <br>
      if/else chain with `if (strstartswith("RandomKey: "))` could
      <br>
      disambiguate it. But maybe it'd be better to have a space at the
      end of
      <br>
      the line so a parser knows when the next line should be a
      continuation,
      <br>
      just like with use "\" in some places. That is better then trying
      all
      <br>
      keys before deciding "never mind, concat with what I was reading
      before".
      <br>
      That may break your guc log parser, but it's probably less drastic
      than
      <br>
      just reverting this whole thing.
      <br>
      <br>
      Lucas De Marchi
      <br>
      <br>
      <blockquote type="cite">
        <br>
        John.
        <br>
        <br>
        <br>
        <blockquote type="cite">
          <br>
          <br>
          <blockquote type="cite">reliable for me.
            <br>
            <br>
            <blockquote type="cite">
              <br>
              Just looked at this code to check if we also had a "Size"
              as I remember
              <br>
              seeing it in previous related patches, but we don't. If
              <br>
              we did then you could use that to calculate how much you
              still had to
              <br>
              read, ignoring the \n. With the current scheme I think one
              <br>
              way would be to continue the previous key when the line
              doesn't start
              <br>
              with a new key. Awful, yes, and not future proof.
              <br>
            </blockquote>
            Any new field is guaranteed to have a colon in it and any
            new section header is guaranteed to have a star in it.
            Sounds pretty reliable to me.
            <br>
          </blockquote>
          <br>
          that's what I said by "continue the previous key when the line
          doesn't
          <br>
          start with a new one".
          <br>
          <br>
          <br>
          <blockquote type="cite">
            <br>
            The other option would be to have an explicit prefix at the
            start of each continuation line. E.g. "A85:".
            <br>
          </blockquote>
          <br>
          let's not make it worse than it already is. And not future
          proof by
          <br>
          given the encoding algorithm the meaning of "continuation
          line".
          <br>
          <br>
          Lucas De Marchi
          <br>
          <br>
          <blockquote type="cite">
            <br>
            The problem with a size field is that ASCII85 encoding is
            data dependent - it has extremely basic run length encoding
            of strings of zeros. So you only know the size after the
            encoding is complete. Which means either the size field is
            in the dump after the encoded data (which is therefore
            useless) or you can't stream the encode and must encode to
            an in-memory buffer first, then print the size, then print
            your pre-encoded data.
            <br>
            <br>
            <br>
            <blockquote type="cite">
              <br>
              John, I explicitly said *we can't break the existent
              users*,
              <br>
              pointed to the one in the mesa repo and confirmed with
              José it would be
              <br>
              indeed a breakage. Please check again the past email
              thread at
              <br>
<a class="moz-txt-link-freetext" href="https://lore.kernel.org/all/3jexgpnh3br3gqi4ol4c3hx3tyhwevq5nqo5xssyie3xglqohz@e7mnj4dewupu/">https://lore.kernel.org/all/3jexgpnh3br3gqi4ol4c3hx3tyhwevq5nqo5xssyie3xglqohz@e7mnj4dewupu/</a>
              <br>
              <br>
              <br>
            </blockquote>
            That discussion was a question for Jose not a statement. As
            there was no response for several weeks, I assumed that it
            wasn't a problem after all.
            <br>
            <br>
            <blockquote type="cite">
              <br>
              Did you at least prepare the mesa parser for that
              additional \n?
              <br>
              <br>
              We shouldn't have merged the kernel patch as is with the
              excuse it reads
              <br>
              better in dmesg, when we also said we should not print
              that garbage to
              <br>
              dmesg :(
              <br>
            </blockquote>
            Not following. Should not print what garbage in dmesg? As I
            keep saying, none of this goes to dmesg by default except in
            the case of catastrophic CT failure. And in that case, it is
            extremely useful and the only way to debug issues.
            <br>
            <br>
            John.
            <br>
            <br>
            <blockquote type="cite">
              <br>
              Lucas De Marchi
              <br>
            </blockquote>
            <br>
          </blockquote>
        </blockquote>
        <br>
      </blockquote>
    </blockquote>
    <br>
  </body>
</html>