Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mem-pool: Fix unaligned access causing fatal SIGBUS on sparc #2669

Merged
merged 3 commits into from
Sep 2, 2021

Conversation

pjakma
Copy link
Contributor

@pjakma pjakma commented Jul 27, 2021

The mem-pool code writes a trailer marker at the end of memory allocations
to sanity check for memory write over-runs. The code does not align the
marker on its required boundary though. This causes unaligned accesses.

Unaligned access may be just slower on some platforms, but on others it can
cause faults and abnormal exits. E.g., this was causing a SIGBUS on
Linux/SPARC64.

Fix by rounding up the header+data size to the needed alignment for the
trailer.

Another solution might be just to remove the trailer code, and rely on other
malloc debugging tools. E.g., LD_PRELOADable malloc debug libraries, GCC
ASAN and so on, valgrind, etc.

@gluster-ant
Copy link
Collaborator

Can one of the admins verify this patch?

2 similar comments
@gluster-ant
Copy link
Collaborator

Can one of the admins verify this patch?

@gluster-ant
Copy link
Collaborator

Can one of the admins verify this patch?

@gluster-ant
Copy link
Collaborator

CLANG-FORMAT FAILURE:
Before merging the patch, this diff needs to be considered for passing clang-format

index c51741f5b..5257cddcb 100644
--- a/libglusterfs/src/glusterfs/mem-pool.h
+++ b/libglusterfs/src/glusterfs/mem-pool.h
@@ -24,7 +24,7 @@
 #include <sys/param.h> /* roundup */
 #ifndef roundup
 /* not a standard, so some platforms may not have it. Define a generic one */
-# define roundup(x, y)  ((((x) + ((y) - 1)) / (y)) * (y))
+#define roundup(x, y) ((((x) + ((y)-1)) / (y)) * (y))
 #endif
 
 /*
@@ -38,7 +38,7 @@
 #include <cmocka.h>
 #endif
 
-typedef  uint32_t gf_mem_magic_t;
+typedef uint32_t gf_mem_magic_t;
 #define GF_MEM_TRAILER_SIZE sizeof(gf_mem_magic_t);
 #define GF_MEM_HEADER_MAGIC 0xCAFEBABE
 #define GF_MEM_TRAILER_MAGIC 0xBAADF00D
diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c
index a8e448387..1c3fcba65 100644
--- a/libglusterfs/src/mem-pool.c
+++ b/libglusterfs/src/mem-pool.c
@@ -48,9 +48,8 @@ __gf_total_alloc_size(size_t req_size)
      * Unaligned access can be fatal on SPARC with gcc compiled code.  On
      * others it can still be slow.
      */
-    return roundup((req_size + GF_MEM_HEADER_SIZE),
-                   alignof(gf_mem_magic_t))
-           + GF_MEM_TRAILER_SIZE;
+    return roundup((req_size + GF_MEM_HEADER_SIZE), alignof(gf_mem_magic_t)) +
+           GF_MEM_TRAILER_SIZE;
 }
 
 static void *
@@ -351,9 +350,9 @@ __gf_free(void *free_ptr)
 
     // This points to a memory overrun
     {
-      void *end = ((char *)ptr) + __gf_total_alloc_size(header->size);
-      gf_mem_magic_t *trailer = end - GF_MEM_TRAILER_SIZE;
-      GF_ASSERT(GF_MEM_TRAILER_MAGIC == *trailer);
+        void *end = ((char *)ptr) + __gf_total_alloc_size(header->size);
+        gf_mem_magic_t *trailer = end - GF_MEM_TRAILER_SIZE;
+        GF_ASSERT(GF_MEM_TRAILER_MAGIC == *trailer);
     }
 
     LOCK(&mem_acct->rec[header->type].lock);
diff --git a/libglusterfs/src/unittest/mem_pool_unittest.c b/libglusterfs/src/unittest/mem_pool_unittest.c
index 67fbc72a1..b75ef0dcd 100644
--- a/libglusterfs/src/unittest/mem_pool_unittest.c
+++ b/libglusterfs/src/unittest/mem_pool_unittest.c
@@ -103,10 +103,9 @@ helper_check_memory_headers(char *mem, xlator_t *xl, size_t size, uint32_t type)
     assert_int_equal(p->size, size);
     assert_true(p->xl == xl);
     assert_int_equal(p->header_magic, GF_MEM_HEADER_MAGIC);
-    assert_true(*(gf_mem_magic_t *)(mem 
-                                    + roundup(sizeof(mem_header_t) + size,
-                                              alignof(gf_mem_magic_t))) 
-                                    == GF_MEM_TRAILER_MAGIC);
+    assert_true(*(gf_mem_magic_t *)(mem + roundup(sizeof(mem_header_t) + size,
+                                                  alignof(gf_mem_magic_t))) ==
+                GF_MEM_TRAILER_MAGIC);
 }
 
 /*

#include <sys/param.h> /* roundup */
#ifndef roundup
/* not a standard, so some platforms may not have it. Define a generic one */
# define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our allocation speed isn't the greatest (using tcmalloc and disabling memory pools seem to provide better performance) - are we sure we want to introduce division and multiplication to the allocation path?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be happy to update this patch to just remove the trailer magic and complexity associated. Faster in the general case, but does not preclude using other tools (runtime or compile) for debugging malloc.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a question for a broader forum of the developer community than in a PR - can you send such a question to the devel mailing list?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth noting the glibc roundup uses a GCC builtin, which IIRC is a single instruction on x86. Other platforms might have similar.

I've added this one for platform compatibility.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that y should always be a power of 2, why not this:

#define roundup(_x, _y) (((_x) + (_y) - 1) & ~((_y) - 1))

@gluster-ant
Copy link
Collaborator

CLANG-FORMAT FAILURE:
Before merging the patch, this diff needs to be considered for passing clang-format

index 67fbc72a1..b75ef0dcd 100644
--- a/libglusterfs/src/unittest/mem_pool_unittest.c
+++ b/libglusterfs/src/unittest/mem_pool_unittest.c
@@ -103,10 +103,9 @@ helper_check_memory_headers(char *mem, xlator_t *xl, size_t size, uint32_t type)
     assert_int_equal(p->size, size);
     assert_true(p->xl == xl);
     assert_int_equal(p->header_magic, GF_MEM_HEADER_MAGIC);
-    assert_true(*(gf_mem_magic_t *)(mem 
-                                    + roundup(sizeof(mem_header_t) + size,
-                                              alignof(gf_mem_magic_t))) 
-                                    == GF_MEM_TRAILER_MAGIC);
+    assert_true(*(gf_mem_magic_t *)(mem + roundup(sizeof(mem_header_t) + size,
+                                                  alignof(gf_mem_magic_t))) ==
+                GF_MEM_TRAILER_MAGIC);
 }
 
 /*

@pjakma
Copy link
Contributor Author

pjakma commented Jul 27, 2021

Anyone know what that "strfmt errors in a 32 build" check is about? I can't find the actionable error in the console output?

@mykaul
Copy link
Contributor

mykaul commented Jul 27, 2021

Anyone know what that "strfmt errors in a 32 build" check is about? I can't find the actionable error in the console output?

Perhaps clang formatting error? Try to run 'clang-format -i ' on your changes first.

@pjakma
Copy link
Contributor Author

pjakma commented Jul 27, 2021

nit: now, in gf_mem_set_acct_info(), you probably want to access the variables in the right order:
instead of:

    header->type = type;
    header->mem_acct = mem_acct;
    header->magic = GF_MEM_HEADER_MAGIC;

You'd do:

    header->mem_acct = mem_acct;
    header->type = type;
    header->magic = GF_MEM_HEADER_MAGIC;

But this is not critical to have in this patch.

Ah, I'll tweak that once this CI run finishes :).

They're not dependent loads, so either the compiler or CPU is free to order them better. So... maybe.. it doesn't matter. But I'll tidy it up.

@pjakma
Copy link
Contributor Author

pjakma commented Jul 29, 2021

I've also tested removing the trailer that works too. I've asked on the list about which way would be better. One reply so far to retain the trailer functionality and fix it: https://lists.gluster.org/pipermail/gluster-devel/2021-July/057286.html

So shall we go with the fix approach?

Without this pull, glusterfs crashes in one of the first memory allocations.

@amarts
Copy link
Member

amarts commented Jul 29, 2021

/run regression

@amarts amarts requested a review from dmantipov July 29, 2021 18:22
@gluster-ant
Copy link
Collaborator

1 test(s) failed
./tests/basic/afr/inodelk.t

1 test(s) generated core
./tests/basic/afr/inodelk.t

3 test(s) needed retry
./tests/000-flaky/basic_mount-nfs-auth.t
./tests/000-flaky/bugs_nfs_bug-1116503.t
./tests/basic/afr/inodelk.t

2 flaky test(s) marked as success even though they failed
./tests/000-flaky/basic_mount-nfs-auth.t
./tests/000-flaky/bugs_nfs_bug-1116503.t
https://build.gluster.org/job/gh_centos7-regression/1475/

@@ -32,7 +38,8 @@
#include <cmocka.h>
#endif

#define GF_MEM_TRAILER_SIZE 8
typedef uint32_t gf_mem_magic_t;
#define GF_MEM_TRAILER_SIZE sizeof(gf_mem_magic_t);
Copy link
Contributor

@dmantipov dmantipov Jul 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra ; at the end of #define is redundant.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doh. New push in a sec.

Copy link
Contributor

@dmantipov dmantipov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@mohit84
Copy link
Contributor

mohit84 commented Jul 31, 2021

/run regression

@gluster-ant
Copy link
Collaborator

1 test(s) failed
./tests/basic/afr/inodelk.t

1 test(s) generated core
./tests/basic/afr/inodelk.t

1 test(s) needed retry
./tests/basic/afr/inodelk.t
https://build.gluster.org/job/gh_centos7-regression/1476/

@pjakma
Copy link
Contributor Author

pjakma commented Jul 31, 2021

When I run that test locally, and it says: "Logs preserved in tarball inodelk-iteration-2.tar" - where has it left that? Doesn't seem to be inside my glusterfs/ code directory?

@itisravi
Copy link
Member

itisravi commented Aug 2, 2021

When I run that test locally, and it says: "Logs preserved in tarball inodelk-iteration-2.tar" - where has it left that? Doesn't seem to be inside my glusterfs/ code directory?

gluster --print-logdir should give you the location, which is usually /var/log/glusterfs.

@pjakma
Copy link
Contributor Author

pjakma commented Aug 2, 2021

/run regression

1 similar comment
@itisravi
Copy link
Member

itisravi commented Aug 3, 2021

/run regression

@gluster-ant
Copy link
Collaborator

1 test(s) failed
./tests/basic/afr/inodelk.t

1 test(s) generated core
./tests/basic/afr/inodelk.t

2 test(s) needed retry
./tests/000-flaky/glusterd-restart-shd-mux.t
./tests/basic/afr/inodelk.t
https://build.gluster.org/job/gh_centos7-regression/1478/

@mykaul
Copy link
Contributor

mykaul commented Aug 3, 2021

1 test(s) failed
./tests/basic/afr/inodelk.t

1 test(s) generated core
./tests/basic/afr/inodelk.t

From the backtrace, looks like it may be somehow related to this patch:

Thread 1 (Thread 0x7f789f93a700 (LWP 10706)):
08:00:12 #0  0x00007f78ae164963 in _list_del (old=0x7f78901afb58) at /home/jenkins/root/workspace/gh_centos7-regression/libglusterfs/src/glusterfs/list.h:78
08:00:12 No locals.
08:00:12 #1  0x00007f78ae164980 in list_del (old=0x7f78901afb58) at /home/jenkins/root/workspace/gh_centos7-regression/libglusterfs/src/glusterfs/list.h:87
08:00:12 No locals.
08:00:12 #2  0x00007f78ae1656f1 in __gf_free (free_ptr=0x7f78901afb68) at /home/jenkins/root/workspace/gh_centos7-regression/libglusterfs/src/mem-pool.c:367
08:00:12         ptr = 0x7f78901afb40
08:00:12         mem_acct = 0x7f789003e0b0
08:00:12         header = 0x7f78901afb40
08:00:12         last_ref = true
08:00:12         __PRETTY_FUNCTION__ = "__gf_free"
08:00:12 #3  0x00007f789e911e36 in dht_local_wipe (local=0x7f78901b8c68) at /home/jenkins/root/workspace/gh_centos7-regression/xlators/cluster/dht/src/dht-helper.c:803
08:00:12         i = 2

Unsure. Not sure I fully understand the comment @

/* The old 'header' already was present in 'obj_list', but

@pjakma
Copy link
Contributor Author

pjakma commented Aug 3, 2021

It's annoying. I get this failure too on my SPARC64 box, but I can't get any useful information from the core (SPARC64 seems to optimise away a lot of the information needed to unpick the stack). Additionally, the SPARC64 is very slow at compiling, so the compile+test cycle takes /ages/.

On a much faster, much more debug-friendly x86-64 this test either doesn't fail, or fails but without a crash/core.

I'll keep picking away at this, in between other work.

Valgrind would be useful. Is there a quick way to get the tests to use valgrind?

@dmantipov
Copy link
Contributor

Valgrind would be useful. Is there a quick way to get the tests to use valgrind?

Sure, reconfigure with --enable-valgrind=memcheck and rebuild. BTW not sure whether valgrind is useful or even working at all on SPARC64.

@itisravi
Copy link
Member

itisravi commented Aug 3, 2021

On a much faster, much more debug-friendly x86-64 this test either doesn't fail, or fails but without a crash/core.

Are you checking the configured core file location on your machine?
The patch generates a core file for me on my x86_64 machine for the .t with all debug symbols in place (I usually compile with --enable-debug). You might not see any indication of a crash when you just run the test ( prove ./tests/basic/afr/inodelk.t) other than the test failing but check the core file location anyway.

@pjakma
Copy link
Contributor Author

pjakma commented Aug 4, 2021

From the backtrace, looks like it may be somehow related to this patch:

Unsure. Not sure I fully understand the comment @

/* The old 'header' already was present in 'obj_list', but

Interesting. Not sure the comment is correct, both list_move and the underlying _list_del it calls write into the old list_head it appears:

list_del(struct list_head *old)

That's UB on realloc'ed memory that's been moved.

pjakma added a commit to pjakma/glusterfs that referenced this pull request Aug 12, 2021
The mem-pool code writes a trailer marker at the end of memory allocations
to sanity check for memory write over-runs.  The code does not align the
marker on its required boundary though. Causing unaligned accesses.

Unaligned access may be just slower on some platforms, but on others it can
cause faults and abnormal exits.  E.g., this was causing a SIGBUS on
Linux/SPARC64.

Possible approaches for a fix:
1. Round up the header+data size to the needed alignment for the
   trailer.

2. Use byte-by-byte memory accesses to write and read the trailer.

Option 1 may sometimes leave a small gap between the end of the allocation
and the trailer, a gap where memory write overruns of the allocations would
not be detected by the trailer check.  Additionally, Option 1 was found to
be slower than Option 2.

Discussion: gluster#2669

So fix the trailer via option 2.
@pjakma
Copy link
Contributor Author

pjakma commented Aug 12, 2021

The differences are minimal (2 ns per read/write at most). However what surprised me is that the alignment actually takes more time than the byte per byte approach. I don't understand why. Could it be because it's using a bit more memory on average ?

Byte-level memory access will be just 1 memory read to cache, and I guess Intel is v good at fixing up unaligned access within a cache-line. I guess sometimes a trailer will straddle cachelines, but it probably had to fetch the memory from the allocation recently anyway. And if DEBUG is on it will (for the case of verifying the trailer on dealloc), in order to poison the memory in __gf_mem_invalidate. So then the removal of the roundup-calculations is the main difference?

Was your performance with or without DEBUG? Likely much harder to see a difference with DEBUG?

@pjakma
Copy link
Contributor Author

pjakma commented Aug 12, 2021

@pjakma if there are no other objections, I'm ok to merge this patch. Can you clean it up to remove the unnecessary aligning code for the byte-level access version ?

I've rebased and squashed the commits into just 3, with all of the alignment fix in one commit, and pushed that!

@xhernandez
Copy link
Contributor

The differences are minimal (2 ns per read/write at most). However what surprised me is that the alignment actually takes more time than the byte per byte approach. I don't understand why. Could it be because it's using a bit more memory on average ?

Byte-level memory access will be just 1 memory read to cache, and I guess Intel is v good at fixing up unaligned access within a cache-line. I guess sometimes a trailer will straddle cachelines, but it probably had to fetch the memory from the allocation recently anyway. And if DEBUG is on it will (for the case of verifying the trailer on dealloc), in order to poison the memory in __gf_mem_invalidate. So then the removal of the roundup-calculations is the main difference?

Was your performance with or without DEBUG? Likely much harder to see a difference with DEBUG?

I simply created a small program to test reading and writing to randomly aligned addresses in different ways, independent from Gluster.

@xhernandez
Copy link
Contributor

/run regression

libglusterfs/src/unittest/mem_pool_unittest.c Outdated Show resolved Hide resolved
Comment on lines 126 to 128

if (subvol_cnt >= 0)
local->ret_cache[subvol_cnt] = op_ret;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is from another patch it shouldn't be here.

libglusterfs/src/unittest/mem_pool_unittest.c Show resolved Hide resolved
@gluster-ant
Copy link
Collaborator

0 test(s) failed

1 test(s) generated core
./tests/bugs/replicate/do-not-reopen-fd.t

4 test(s) needed retry
./tests/000-flaky/basic_mount-nfs-auth.t
./tests/000-flaky/bugs_nfs_bug-1116503.t
./tests/000-flaky/glusterd-restart-shd-mux.t
./tests/bugs/replicate/bug-986905.t

2 flaky test(s) marked as success even though they failed
./tests/000-flaky/basic_mount-nfs-auth.t
./tests/000-flaky/bugs_nfs_bug-1116503.t
https://build.gluster.org/job/gh_centos7-regression/1522/

@amarts
Copy link
Member

amarts commented Aug 24, 2021

/run regression

@gluster-ant
Copy link
Collaborator

1 test(s) failed
./tests/bugs/replicate/bug-880898.t

0 test(s) generated core

3 test(s) needed retry
./tests/000-flaky/glusterd-restart-shd-mux.t
./tests/basic/volume-snapshot-clone.t
./tests/bugs/replicate/bug-880898.t

1 flaky test(s) marked as success even though they failed
./tests/000-flaky/glusterd-restart-shd-mux.t
https://build.gluster.org/job/gh_centos7-regression/1549/

Can put a ZLA at the end of the mem header to automatically get generally
the optimal padding at the end of the struct for the following data.
@pjakma
Copy link
Contributor Author

pjakma commented Aug 25, 2021

I don't see how this unit test gets run. My own make check locally doesn't seem to compile / run it. I don't see the file name referenced anywhere?

@mohit84
Copy link
Contributor

mohit84 commented Aug 25, 2021

/run regression

@mohit84
Copy link
Contributor

mohit84 commented Aug 25, 2021

/run full regression

pjakma added a commit to pjakma/glusterfs that referenced this pull request Aug 25, 2021
The mem-pool code writes a trailer marker at the end of memory allocations
to sanity check for memory write over-runs.  The code does not align the
marker on its required boundary though. Causing unaligned accesses.

Unaligned access may be just slower on some platforms, but on others it can
cause faults and abnormal exits.  E.g., this was causing a SIGBUS on
Linux/SPARC64.

Possible approaches for a fix:
1. Round up the header+data size to the needed alignment for the
   trailer.

2. Use byte-by-byte memory accesses to write and read the trailer.

Option 1 may sometimes leave a small gap between the end of the allocation
and the trailer, a gap where memory write overruns of the allocations would
not be detected by the trailer check.  Additionally, Option 1 was found to
be slower than Option 2.

Discussion: gluster#2669

So fix the trailer via option 2.
@gluster-ant
Copy link
Collaborator

CLANG-FORMAT FAILURE:
Before merging the patch, this diff needs to be considered for passing clang-format

index 3db727758..84242ca36 100644
--- a/libglusterfs/src/unittest/mem_pool_unittest.c
+++ b/libglusterfs/src/unittest/mem_pool_unittest.c
@@ -44,15 +44,16 @@ typedef struct {
 int
 gf_mem_set_acct_info(xlator_t *xl, char **alloc_ptr, size_t size, uint32_t type,
                      const char *typestr);
-size_t __gf_total_alloc_size(size_t req_size);
-void __gf_mem_trailer_write(uint8_t *trailer)
-gf_mem_magic_t __gf_mem_trailer_read(uint8_t *trailer)
-
-/*
- * Helper functions
- */
-static xlator_t *
-helper_xlator_init(uint32_t num_types)
+size_t
+__gf_total_alloc_size(size_t req_size);
+void
+__gf_mem_trailer_write(uint8_t *trailer) gf_mem_magic_t
+    __gf_mem_trailer_read(uint8_t *trailer)
+
+    /*
+     * Helper functions
+     */
+    static xlator_t *helper_xlator_init(uint32_t num_types)
 {
     xlator_t *xl;
     int i, ret;
@@ -105,8 +106,8 @@ helper_check_memory_headers(char *mem, xlator_t *xl, size_t size, uint32_t type)
     assert_int_equal(p->size, size);
     assert_true(p->xl == xl);
     assert_int_equal(p->header_magic, GF_MEM_HEADER_MAGIC);
-    assert_true(__gf_mem_trailer_read((uint8_t *)mem + sizeof(mem_header_t) + size) ==
-                GF_MEM_TRAILER_MAGIC);
+    assert_true(__gf_mem_trailer_read((uint8_t *)mem + sizeof(mem_header_t) +
+                                      size) == GF_MEM_TRAILER_MAGIC);
 }
 
 /*

The mem-pool code writes a trailer marker at the end of memory allocations
to sanity check for memory write over-runs.  The code does not align the
marker on its required boundary though. Causing unaligned accesses.

Unaligned access may be just slower on some platforms, but on others it can
cause faults and abnormal exits.  E.g., this was causing a SIGBUS on
Linux/SPARC64.

Possible approaches for a fix:
1. Round up the header+data size to the needed alignment for the
   trailer.

2. Use byte-by-byte memory accesses to write and read the trailer.

Option 1 may sometimes leave a small gap between the end of the allocation
and the trailer, a gap where memory write overruns of the allocations would
not be detected by the trailer check.  Additionally, Option 1 was found to
be slower than Option 2.

Discussion: gluster#2669

So fix the trailer via option 2.
As per mykaul's suggestion, try re-arrange the struct to minimise padding.
Move the obviously larger types to earlier in the struct.
@gluster-ant
Copy link
Collaborator

5 test(s) needed retry
./tests/000-flaky/basic_mount-nfs-auth.t
./tests/000-flaky/bugs_nfs_bug-1116503.t
./tests/basic/quick-read-with-upcall.t
./tests/bugs/glusterd/serialize-shd-manager-glusterd-restart.t
./tests/bugs/replicate/do-not-reopen-fd.t

2 flaky test(s) marked as success even though they failed
./tests/000-flaky/basic_mount-nfs-auth.t
./tests/000-flaky/bugs_nfs_bug-1116503.t

@pjakma
Copy link
Contributor Author

pjakma commented Aug 29, 2021

Can we merge this now? I addressed that comment of @xhernandez's by rebasing, but github doesn't allow me to to resolve it because that commit/file obviously isn't there anymore.

@pjakma
Copy link
Contributor Author

pjakma commented Aug 29, 2021

/run full regression

@amarts
Copy link
Member

amarts commented Aug 30, 2021

/run regression

Copy link
Member

@amarts amarts left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@amarts
Copy link
Member

amarts commented Sep 2, 2021

I checked @xhernandez's request for changes, and seems like thats now addressed. And hence merging this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants