Fixing parallel make of libpq

Started by Nonameabout 6 years ago8 messages
#1Noname
ilmari@ilmari.org
1 attachment(s)

Hi hackers,

I noticed to my annoyance that 'make -j4 -C src/interfaces/libpq'
doesn't work in a clean checkout, because it can't find
libpgcommon_shlib and libpgport_shlib. It looks like that's because the
submake-libpgport dependency is declared on the all-lib target, not on
the shlib itself. Moving it to SHLIB_PREREQS instead fixes it, patch
for which is attached.

- ilmari
--
- Twitter seems more influential [than blogs] in the 'gets reported in
the mainstream press' sense at least. - Matt McLeod
- That'd be because the content of a tweet is easier to condense down
to a mainstream media article. - Calle Dybedahl

Attachments:

0001-Make-libpgport-a-dependency-of-the-libpq-shlib-itsel.patchtext/x-diffDownload
From 08296fc98aafdaa60045275d592bbe0a364311c9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dagfinn=20Ilmari=20Manns=C3=A5ker?= <ilmari@ilmari.org>
Date: Wed, 8 Jan 2020 13:20:13 +0000
Subject: [PATCH] Make libpgport a dependency of the libpq shlib itself, not
 the all-lib

This fixes parallel make of libpq in clean source directory.
---
 src/interfaces/libpq/Makefile | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/interfaces/libpq/Makefile b/src/interfaces/libpq/Makefile
index 773ef2723d..2511d6f771 100644
--- a/src/interfaces/libpq/Makefile
+++ b/src/interfaces/libpq/Makefile
@@ -94,9 +94,9 @@ endif
 
 SHLIB_EXPORTS = exports.txt
 
-all: all-lib
+SHLIB_PREREQS = submake-libpgport
 
-all-lib: | submake-libpgport
+all: all-lib
 
 # Shared library stuff
 include $(top_srcdir)/src/Makefile.shlib
-- 
2.20.1

#2Michael Paquier
michael@paquier.xyz
In reply to: Noname (#1)
Re: Fixing parallel make of libpq

On Wed, Jan 08, 2020 at 01:33:13PM +0000, Dagfinn Ilmari Mannsåker wrote:

I noticed to my annoyance that 'make -j4 -C src/interfaces/libpq'
doesn't work in a clean checkout, because it can't find
libpgcommon_shlib and libpgport_shlib. It looks like that's because the
submake-libpgport dependency is declared on the all-lib target, not on
the shlib itself. Moving it to SHLIB_PREREQS instead fixes it, patch
for which is attached.

Hmm. That logically makes sense. Isn't that a side effect of 7143b3e
then? Now, FWIW, I am not able to reproduce it here, after trying on
two different machines, various parallel job numbers (up to 32), and a
couple of dozen attempts. Perhaps somebody else can see the failures?
--
Michael

#3Noname
ilmari@ilmari.org
In reply to: Michael Paquier (#2)
2 attachment(s)
Re: Fixing parallel make of libpq

Michael Paquier <michael@paquier.xyz> writes:

On Wed, Jan 08, 2020 at 01:33:13PM +0000, Dagfinn Ilmari Mannsåker wrote:

I noticed to my annoyance that 'make -j4 -C src/interfaces/libpq'
doesn't work in a clean checkout, because it can't find
libpgcommon_shlib and libpgport_shlib. It looks like that's because the
submake-libpgport dependency is declared on the all-lib target, not on
the shlib itself. Moving it to SHLIB_PREREQS instead fixes it, patch
for which is attached.

Hmm. That logically makes sense. Isn't that a side effect of 7143b3e
then? Now, FWIW, I am not able to reproduce it here, after trying on
two different machines, various parallel job numbers (up to 32), and a
couple of dozen attempts. Perhaps somebody else can see the failures?

It fails reliably for me on Debian Buster, with make 4.2.1-1.2and -j4.
The command to reproduce it is:

git clean -xfd && ./configure && make -Otarget -j4 -C src/interfaces/libpq/

Attached is the output of the `make` step with and without the patch.

- ilmari
--
- Twitter seems more influential [than blogs] in the 'gets reported in
the mainstream press' sense at least. - Matt McLeod
- That'd be because the content of a tweet is easier to condense down
to a mainstream media article. - Calle Dybedahl

Attachments:

make-libpq-parallel.logtext/plainDownload
make-libpq-parallel-fixed.logtext/plainDownload
#4Tom Lane
tgl@sss.pgh.pa.us
In reply to: Noname (#3)
Re: Fixing parallel make of libpq

ilmari@ilmari.org (Dagfinn Ilmari =?utf-8?Q?Manns=C3=A5ker?=) writes:

Michael Paquier <michael@paquier.xyz> writes:

Hmm. That logically makes sense. Isn't that a side effect of 7143b3e
then? Now, FWIW, I am not able to reproduce it here, after trying on
two different machines, various parallel job numbers (up to 32), and a
couple of dozen attempts. Perhaps somebody else can see the failures?

It fails reliably for me on Debian Buster, with make 4.2.1-1.2and -j4.

Yeah, it's also reliable for me on Fedora 30:

$ make -s clean
$ make -s -j4 -C src/interfaces/libpq
/usr/bin/ld: cannot find -lpgcommon_shlib
/usr/bin/ld: cannot find -lpgport_shlib
collect2: error: ld returned 1 exit status
make: *** [../../../src/Makefile.shlib:293: libpq.so.5.13] Error 1
make: *** Waiting for unfinished jobs....

On a RHEL6 box, the same test only draws a complaint about
-lpgcommon_shlib, so it does seem like there's some make version
dependency in here. And of course the whole thing is a race condition
anyway, so naturally it's going to be pretty context-sensitive.

My thoughts about the patch:

1) Changing from an "|"-style dependency to a plain dependency seems
like a semantics change. I've never been totally clear on the
difference though. I think Peter introduced our use of the "|" style,
so maybe he can comment.

2) The same coding pattern is used in a bunch of other places, so if
this spot is broken, there probably are a lot of others that need a
similar change. On the other hand, there may not be that many
directories that are likely places to start a parallel build from,
so maybe we don't care elsewhere.

regards, tom lane

#5Noname
ilmari@ilmari.org
In reply to: Tom Lane (#4)
Re: Fixing parallel make of libpq

Tom Lane <tgl@sss.pgh.pa.us> writes:

My thoughts about the patch:

1) Changing from an "|"-style dependency to a plain dependency seems
like a semantics change. I've never been totally clear on the
difference though. I think Peter introduced our use of the "|" style,
so maybe he can comment.

Makefile.shlib puts $(SHLIB_PREREQS) after the "|":

$ grep SHLIB_PREREQS src/Makefile.shlib
# SHLIB_PREREQS Order-only prerequisites for library build target
$(stlib): $(OBJS) | $(SHLIB_PREREQS)
$(shlib): $(OBJS) | $(SHLIB_PREREQS)
$(shlib): $(OBJS) | $(SHLIB_PREREQS)
$(shlib): $(OBJS) | $(SHLIB_PREREQS)
$(shlib): $(OBJS) | $(SHLIB_PREREQS)
$(shlib): $(OBJS) $(DLL_DEFFILE) | $(SHLIB_PREREQS)

2) The same coding pattern is used in a bunch of other places, so if
this spot is broken, there probably are a lot of others that need a
similar change. On the other hand, there may not be that many
directories that are likely places to start a parallel build from,
so maybe we don't care elsewhere.

Grepping the Makefiles for ':.*submake-' shows that they are on the
actual build artifact target, libpq was just the outlier having it on
the phony "all" target. For example pg_basebackup:

pg_basebackup: pg_basebackup.o $(OBJS) | submake-libpq submake-libpgport submake-libpgfeutils
$(CC) $(CFLAGS) pg_basebackup.o $(OBJS) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)

pg_receivewal: pg_receivewal.o $(OBJS) | submake-libpq submake-libpgport submake-libpgfeutils
$(CC) $(CFLAGS) pg_receivewal.o $(OBJS) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)

pg_recvlogical: pg_recvlogical.o $(OBJS) | submake-libpq submake-libpgport submake-libpgfeutils
$(CC) $(CFLAGS) pg_recvlogical.o $(OBJS) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)

- ilmari
--
"A disappointingly low fraction of the human race is,
at any given time, on fire." - Stig Sandbeck Mathisen

#6Peter Eisentraut
peter.eisentraut@2ndquadrant.com
In reply to: Tom Lane (#4)
Re: Fixing parallel make of libpq

On 2020-01-09 15:17, Tom Lane wrote:

1) Changing from an "|"-style dependency to a plain dependency seems
like a semantics change. I've never been totally clear on the
difference though. I think Peter introduced our use of the "|" style,
so maybe he can comment.

If you have a phony target as a prerequisite of a real-file target, you
should make that an order-only ("|") prerequisite. Otherwise the
real-file target rules will *always* be run, on account of the phony
target prerequisite.

--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

#7Tom Lane
tgl@sss.pgh.pa.us
In reply to: Peter Eisentraut (#6)
Re: Fixing parallel make of libpq

Peter Eisentraut <peter.eisentraut@2ndquadrant.com> writes:

On 2020-01-09 15:17, Tom Lane wrote:

1) Changing from an "|"-style dependency to a plain dependency seems
like a semantics change. I've never been totally clear on the
difference though. I think Peter introduced our use of the "|" style,
so maybe he can comment.

If you have a phony target as a prerequisite of a real-file target, you
should make that an order-only ("|") prerequisite. Otherwise the
real-file target rules will *always* be run, on account of the phony
target prerequisite.

OK, got that. But that doesn't directly answer the question of whether
it's wrong to use a phony target as an order-only prerequisite of
another phony target. Grepping around for other possible issues,
I see that you recently added

update-unicode: | submake-generated-headers submake-libpgport
$(MAKE) -C src/common/unicode $@
$(MAKE) -C contrib/unaccent $@

Doesn't that also have parallel-make hazards, if libpq does?

regards, tom lane

#8Noname
ilmari@ilmari.org
In reply to: Tom Lane (#7)
1 attachment(s)
Re: Fixing parallel make of libpq

Tom Lane <tgl@sss.pgh.pa.us> writes:

OK, got that. But that doesn't directly answer the question of whether
it's wrong to use a phony target as an order-only prerequisite of
another phony target. Grepping around for other possible issues,
I see that you recently added

update-unicode: | submake-generated-headers submake-libpgport
$(MAKE) -C src/common/unicode $@
$(MAKE) -C contrib/unaccent $@

Doesn't that also have parallel-make hazards, if libpq does?

The part of 'update-unicode' that needs the generated headers and
libpgport is src/common/unicode/norm_test, which is depended by on by
the normalization-check target in the same directory. Running 'make -C
src/common/unicode normalization-check' in a freshly-configured tree
does indeed fail, independent of parallelism or the update-unicode
target.

Adding the deps to the norm_test target fixes 'make -C
src/common/unicode normalization-check', but 'make -C src/common/unicode
update-unicode' still fails, because submake-generated-headers only does
its thing in the top-level make invocation, so that needs an explicit
dep as well.

Please find a patch attached. However, I don't think it's fair to block
fixing the actual libpq parallel-make bug that has bitten me several
times on auditing the entire source tree for vaguely related issues that
nobody has complained about yet.

- ilmari
--
"A disappointingly low fraction of the human race is,
at any given time, on fire." - Stig Sandbeck Mathisen

Attachments:

0001-Add-missing-dependencies-in-src-common-unicode-Makef.patchtext/x-diffDownload
From df05722a6b287d909698becb9718acce78a88020 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dagfinn=20Ilmari=20Manns=C3=A5ker?= <ilmari@ilmari.org>
Date: Mon, 24 Feb 2020 00:03:54 +0000
Subject: [PATCH] Add missing dependencies in src/common/unicode/Makefile

The norm_test program needs the generated headers and libpgport.

Because the submake-generated-headers target only does its thing in a
top-level make, add it to the update-unicode target too, so that doing
'make update-unicode' in this directory works, not just in the top
directory.
---
 src/common/unicode/Makefile | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/common/unicode/Makefile b/src/common/unicode/Makefile
index ec78aeec2a..8e92eabdea 100644
--- a/src/common/unicode/Makefile
+++ b/src/common/unicode/Makefile
@@ -18,7 +18,7 @@ LIBS += $(PTHREAD_LIBS)
 # By default, do nothing.
 all:
 
-update-unicode: unicode_norm_table.h unicode_combining_table.h
+update-unicode: unicode_norm_table.h unicode_combining_table.h | submake-generated-headers
 	$(MAKE) normalization-check
 	mv unicode_norm_table.h unicode_combining_table.h ../../../src/include/common/
 
@@ -40,7 +40,7 @@ unicode_combining_table.h: generate-unicode_combining_table.pl UnicodeData.txt
 normalization-check: norm_test
 	./norm_test
 
-norm_test: norm_test.o ../unicode_norm.o
+norm_test: norm_test.o ../unicode_norm.o | submake-generated-headers submake-libpgport
 
 norm_test.o: norm_test_table.h
 
-- 
2.22.0