Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 27 Jul 2016 09:44:56 +0300
From:      Andriy Gapon <avg@FreeBSD.org>
To:        Dimitry Andric <dim@FreeBSD.org>, "freebsd-hackers@freebsd.org" <freebsd-hackers@FreeBSD.org>
Subject:   problem when compiling zfs.ko with clang with O1 on amd64
Message-ID:  <667ac922-533f-2d37-706e-93fa9b069034@FreeBSD.org>

next in thread | raw e-mail | index | archive | help

First of all, what I describe next happens only when compiling with -O1
which is a non-standard option that I used to get better debugging.

So, I compile zfs module with clang on amd64 head.
Clang is:
FreeBSD clang version 3.8.0 (tags/RELEASE_380/final 262564) (based on
LLVM 3.8.0)

When -O1 is used I see that statements like 'T x = { 0 };' are
translated to calls to external memset function with the standard arguments.

On the other hand, since recently a few ZFS source files (all hash
related: sha256c.c, sha512c.c, skein.c) have explicit calls to memset(x,
0, s).  Those get inlined but in a particular fashion: a local memset
function is generated in each file, the function is a very thin wrapper
around bzero and it expects the same argument as bzero.

Because of how kernel loadable modules are implemented on amd64 the
external calls to memset get resolved to the first of the local
functions.  Because of the mismatch between the arguments provided and
the arguments expected the effective calls are 'bzero(x, 0)', NOPs that is.

I am not sure if I can blame clang here.  It is probably correct to
expect that it can generate a _local_ function named 'memset' without
interfering without other compilation units.  However, that can be
unhelpful as we can see.

Some data:
$ nm -A --defined-only *.o | fgrep -w memset
sha256c.o:0000000000000e60 t memset
sha512c.o:00000000000010f0 t memset
skein.o:0000000000000120 t memset

$ nm /boot/kernel.z/zfs.ko | fgrep -w memset
0000000000019030 t memset
0000000000017e60 t memset
0000000000019500 t memset
                 U memset


Assembly of one of the local memset functions:
.align 16, 0x90
.type  memset, @function

memset:
# @memset
.Lfunc_begin6:
	.file 5 "/usr/src/sys/sys" "libkern.h"
	.loc  5 187 0                 # /usr/src/sys/sys/libkern.h:187:0
	.cfi_startproc

# BB#0:                                 # %entry
	pushq %rbp

.Ltmp105:
	.cfi_def_cfa_offset 16

.Ltmp106:
	.cfi_offset %rbp, -16
	movq %rsp, %rbp

.Ltmp107:
	.cfi_def_cfa_register %rbp

#DEBUG_VALUE: memset:c <- 0
.loc 5 191 3 prologue_end    # /usr/src/sys/sys/libkern.h:191:3

.Ltmp108:
	popq %rbp
	jmp  bzero                   # TAILCALL

.Ltmp109:
.Lfunc_end6:
	.size memset, .Lfunc_end6-memset
	.cfi_endproc


-- 
Andriy Gapon



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?667ac922-533f-2d37-706e-93fa9b069034>