Skip to content

Commit

Permalink
ARC: build: move symlink creation to arch/arc/Makefile to avoid race
Browse files Browse the repository at this point in the history
If you run 'make uImage uImage.gz' with the parallel option, uImage.gz
will be created by two threads simultaneously.

This is because arch/arc/Makefile does not specify the dependency
between uImage and uImage.gz. Hence, GNU Make assumes they can be
built in parallel. One thread descends into arch/arc/boot/ to create
uImage, and another to create uImage.gz.

Please notice the same log is displayed twice in the following steps:

  $ export CROSS_COMPILE=<your-arc-compiler-prefix>
  $ make -s ARCH=arc defconfig
  $ make -j$(nproc) ARCH=arc uImage uImage.gz
  [ snip ]
    LD      vmlinux
    SORTTAB vmlinux
    SYSMAP  System.map
    OBJCOPY arch/arc/boot/vmlinux.bin
    OBJCOPY arch/arc/boot/vmlinux.bin
    GZIP    arch/arc/boot/vmlinux.bin.gz
    GZIP    arch/arc/boot/vmlinux.bin.gz
    UIMAGE  arch/arc/boot/uImage.gz
    UIMAGE  arch/arc/boot/uImage.gz
  Image Name:   Linux-5.10.0-rc4-00003-g62f23044
  Created:      Sun Nov 22 02:52:26 2020
  Image Type:   ARC Linux Kernel Image (gzip compressed)
  Data Size:    2109376 Bytes = 2059.94 KiB = 2.01 MiB
  Load Address: 80000000
  Entry Point:  80004000
    Image arch/arc/boot/uImage is ready
  Image Name:   Linux-5.10.0-rc4-00003-g62f23044
  Created:      Sun Nov 22 02:52:26 2020
  Image Type:   ARC Linux Kernel Image (gzip compressed)
  Data Size:    2815455 Bytes = 2749.47 KiB = 2.69 MiB
  Load Address: 80000000
  Entry Point:  80004000

This is a race between the two threads trying to write to the same file
arch/arc/boot/uImage.gz. This is a potential problem that can generate
a broken file.

I fixed a similar problem for ARM by commit 3939f33 ("ARM: 8418/1:
add boot image dependencies to not generate invalid images").

I highly recommend to avoid such build rules that cause a race condition.

Move the uImage rule to arch/arc/Makefile.

Another strangeness is that arch/arc/boot/Makefile compares the
timestamps between $(obj)/uImage and $(obj)/uImage.*:

  $(obj)/uImage: $(obj)/uImage.$(suffix-y)
          @ln -sf $(notdir $<) $@
          @echo '  Image $@ is ready'

This does not work as expected since $(obj)/uImage is a symlink.
The symlink should be created in a phony target rule.

I used $(kecho) instead of echo to suppress the message
'Image arch/arc/boot/uImage is ready' when the -s option is given.

Signed-off-by: Masahiro Yamada <[email protected]>
Signed-off-by: Vineet Gupta <[email protected]>
  • Loading branch information
masahir0y authored and vineetgarc committed Dec 2, 2020
1 parent 0cfccb3 commit c5e6ae5
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 11 deletions.
13 changes: 12 additions & 1 deletion arch/arc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,22 @@ libs-y += arch/arc/lib/ $(LIBGCC)

boot := arch/arc/boot

boot_targets := uImage uImage.bin uImage.gz uImage.lzma
boot_targets := uImage.bin uImage.gz uImage.lzma

PHONY += $(boot_targets)
$(boot_targets): vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@

uimage-default-y := uImage.bin
uimage-default-$(CONFIG_KERNEL_GZIP) := uImage.gz
uimage-default-$(CONFIG_KERNEL_LZMA) := uImage.lzma

PHONY += uImage
uImage: $(uimage-default-y)
@ln -sf $< $(boot)/uImage
@$(kecho) ' Image $(boot)/uImage is ready'

CLEAN_FILES += $(boot)/uImage

archclean:
$(Q)$(MAKE) $(clean)=$(boot)
11 changes: 1 addition & 10 deletions arch/arc/boot/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
targets := vmlinux.bin vmlinux.bin.gz uImage
targets := vmlinux.bin vmlinux.bin.gz

# uImage build relies on mkimage being availble on your host for ARC target
# You will need to build u-boot for ARC, rename mkimage to arc-elf32-mkimage
Expand All @@ -13,11 +13,6 @@ LINUX_START_TEXT = $$(readelf -h vmlinux | \
UIMAGE_LOADADDR = $(CONFIG_LINUX_LINK_BASE)
UIMAGE_ENTRYADDR = $(LINUX_START_TEXT)

suffix-y := bin
suffix-$(CONFIG_KERNEL_GZIP) := gz
suffix-$(CONFIG_KERNEL_LZMA) := lzma

targets += uImage
targets += uImage.bin
targets += uImage.gz
targets += uImage.lzma
Expand All @@ -42,7 +37,3 @@ $(obj)/uImage.gz: $(obj)/vmlinux.bin.gz FORCE

$(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma FORCE
$(call if_changed,uimage,lzma)

$(obj)/uImage: $(obj)/uImage.$(suffix-y)
@ln -sf $(notdir $<) $@
@echo ' Image $@ is ready'

0 comments on commit c5e6ae5

Please sign in to comment.