From 67624495c3d1309f96bea37f3fc8bc41d46990aa Mon Sep 17 00:00:00 2001 From: Hamish Mackenzie Date: Thu, 18 Mar 2021 18:59:22 +1300 Subject: [PATCH 1/4] Add GHC 8.10 Make markLiveObject thread-safe See https://github.com/input-output-hk/haskell.nix/issues/1062 --- overlays/bootstrap.nix | 2 + ...-rts-make-markLiveObject-thread-safe.patch | 63 +++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 overlays/patches/ghc/ghc-8.10.3-rts-make-markLiveObject-thread-safe.patch diff --git a/overlays/bootstrap.nix b/overlays/bootstrap.nix index 6907ca2e0a..4e91da6646 100644 --- a/overlays/bootstrap.nix +++ b/overlays/bootstrap.nix @@ -151,6 +151,8 @@ in { ++ fromUntil "8.10.1" "8.10.3" ./patches/ghc/ghc-8.10-ubxt.patch ++ fromUntil "8.10.3" "8.11" ./patches/ghc/ghc-8.10.3-ubxt.patch ++ final.lib.optional (versionAtLeast "8.6.4") ./patches/ghc/Cabal-3886.patch + + ++ fromUntil "8.10.3" "8.10.5" ./patches/ghc/ghc-8.10.3-rts-make-markLiveObject-thread-safe.patch ; in ({ ghc844 = final.callPackage ../compiler/ghc { diff --git a/overlays/patches/ghc/ghc-8.10.3-rts-make-markLiveObject-thread-safe.patch b/overlays/patches/ghc/ghc-8.10.3-rts-make-markLiveObject-thread-safe.patch new file mode 100644 index 0000000000..1b3bb0e29a --- /dev/null +++ b/overlays/patches/ghc/ghc-8.10.3-rts-make-markLiveObject-thread-safe.patch @@ -0,0 +1,63 @@ +From 96f8e2a47c5e53ae5fb86739aecd27c502e7f121 Mon Sep 17 00:00:00 2001 +From: Ben Gamari +Date: Tue, 23 Feb 2021 18:30:48 +0000 +Subject: [PATCH] rts: Make markLiveObject thread-safe + +markLiveObject is called by GC worker threads and therefore must be +thread-safe. This was a rather egregious oversight which the testsuite +missed. + + +(cherry picked from commit fe28a062e47bd914a6879f2d01ff268983c075ad) +--- + rts/CheckUnload.c | 10 ++++++++-- + rts/LinkerInternals.h | 2 +- + 2 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/rts/CheckUnload.c b/rts/CheckUnload.c +index 8f834d13fa..345a17cfec 100644 +--- a/rts/CheckUnload.c ++++ b/rts/CheckUnload.c +@@ -381,11 +381,16 @@ static ObjectCode *findOC(OCSectionIndices *s_indices, const void *addr) { + + static bool markObjectLive(void *data STG_UNUSED, StgWord key, const void *value STG_UNUSED) { + ObjectCode *oc = (ObjectCode*)key; +- if (oc->mark == object_code_mark_bit) { ++ ++ // N.B. we may be called by the parallel GC and therefore this must be ++ // thread-safe. To avoid taking the linker_mutex in the fast path ++ // (when the object is already marked) we do an atomic exchange here and ++ // only take the lock in the case that the object is unmarked. ++ if (xchg(&oc->mark, object_code_mark_bit) == object_code_mark_bit) { + return true; // for hash table iteration + } + +- oc->mark = object_code_mark_bit; ++ ACQUIRE_LOCK(&linker_mutex); + // Remove from 'old_objects' list + if (oc->prev != NULL) { + // TODO(osa): Maybe 'prev' should be a pointer to the referencing +@@ -405,6 +410,7 @@ static bool markObjectLive(void *data STG_UNUSED, StgWord key, const void *value + objects->prev = oc; + } + objects = oc; ++ RELEASE_LOCK(&linker_mutex); + + // Mark its dependencies + iterHashTable(oc->dependencies, NULL, markObjectLive); +diff --git a/rts/LinkerInternals.h b/rts/LinkerInternals.h +index 44fe337802..444849fbac 100644 +--- a/rts/LinkerInternals.h ++++ b/rts/LinkerInternals.h +@@ -262,7 +262,7 @@ struct _ObjectCode { + struct _ObjectCode *next_loaded_object; + + // Mark bit +- uint8_t mark; ++ StgWord mark; + + // Set of dependencies (ObjectCode*) of the object file. Traverse + // dependencies using `iterHashTable`. +-- +GitLab + From db8fdac2524e58d0785c44c454d703e7294dd230 Mon Sep 17 00:00:00 2001 From: Hamish Mackenzie Date: Thu, 18 Mar 2021 21:32:01 +1300 Subject: [PATCH 2/4] ifdLevel 1 --- release.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release.nix b/release.nix index f00eba2ae3..ca3de7a550 100644 --- a/release.nix +++ b/release.nix @@ -1,7 +1,7 @@ # 'supportedSystems' restricts the set of systems that we will evaluate for. Useful when you're evaluating # on a machine with e.g. no way to build the Darwin IFDs you need! { supportedSystems ? [ "x86_64-linux" "x86_64-darwin" ] -, ifdLevel ? 3 +, ifdLevel ? 1 , checkMaterialization ? false }: let From 6e865916f0aa14695db713b41f31dd80c237d2cc Mon Sep 17 00:00:00 2001 From: Hamish Mackenzie Date: Fri, 19 Mar 2021 01:19:01 +1300 Subject: [PATCH 3/4] ifdLevel 2 --- release.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release.nix b/release.nix index ca3de7a550..02cb1f61d3 100644 --- a/release.nix +++ b/release.nix @@ -1,7 +1,7 @@ # 'supportedSystems' restricts the set of systems that we will evaluate for. Useful when you're evaluating # on a machine with e.g. no way to build the Darwin IFDs you need! { supportedSystems ? [ "x86_64-linux" "x86_64-darwin" ] -, ifdLevel ? 1 +, ifdLevel ? 2 , checkMaterialization ? false }: let From 460833dc50aed528004d59fe989f4c8ff7eb4993 Mon Sep 17 00:00:00 2001 From: Hamish Mackenzie Date: Fri, 19 Mar 2021 12:32:25 +1300 Subject: [PATCH 4/4] ifdLevel 3 --- release.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release.nix b/release.nix index 02cb1f61d3..f00eba2ae3 100644 --- a/release.nix +++ b/release.nix @@ -1,7 +1,7 @@ # 'supportedSystems' restricts the set of systems that we will evaluate for. Useful when you're evaluating # on a machine with e.g. no way to build the Darwin IFDs you need! { supportedSystems ? [ "x86_64-linux" "x86_64-darwin" ] -, ifdLevel ? 2 +, ifdLevel ? 3 , checkMaterialization ? false }: let