diff options
author | David Howells <dhowells@redhat.com> | 2007-02-05 19:21:08 -0500 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2007-02-10 11:00:49 -0500 |
commit | 6bdd61d876e6eacea5c59230b6b2d988b22793e6 (patch) | |
tree | a375d2866f2e6a627ccbea90900bbd37ef10045b | |
parent | 839fcaba355abaffb7b44f0f4504093acb0b11cf (diff) |
IB/mthca: Work around gcc bug on sparc64
For some reason gcc-3.4.5 on sparc64 does:
WARNING: "____ilog2_NaN" [drivers/infiniband/hw/mthca/ib_mthca.ko] undefined!
Points to note:
(1) The asm volatile flush/flushw are just markers for viewing what comes out
in the assembly; removing them has no effect on the result.
(2) Changing almost anything else in dwh__mthca_arbel_init_srq_context() or
dwh__mthca_alloc_srq() causes the problem to go away.
The compiler command line issued by the kernel build is:
/opt/crosstool/gcc-3.4.5-glibc-2.3.6/sparc64-unknown-linux-gnu/bin/sparc64-unknown-linux-gnu-gcc -fno-strict-aliasing -fno-common -Os -m64 -mno-fpu -mcpu=ultrasparc -mcmodel=medlow -ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wa,--undeclared-regs -pg -fno-omit-frame-pointer -fno-optimize-sibling-calls -fasynchronous-unwind-tables -g -c -o drivers/infiniband/hw/mthca/.tmp_mthca_srq.o drivers/infiniband/hw/mthca/mthca_srq.c
This can be reduced to this whilst still retaining the problem:
/opt/crosstool/gcc-3.4.5-glibc-2.3.6/sparc64-unknown-linux-gnu/bin/sparc64-unknown-linux-gnu-gcc -m64 -c -o drivers/infiniband/hw/mthca/mthca_srq.o drivers/infiniband/hw/mthca/mthca_srq.c -Os
Removing -Os or changing it to -O or -O0 thru -O6 gets rid of the problem.
This patch to the kernel code fixes the problem:
Cc: "David S. Miller" <davem@davemloft.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_srq.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c index 10684da33d58..61974b0296ca 100644 --- a/drivers/infiniband/hw/mthca/mthca_srq.c +++ b/drivers/infiniband/hw/mthca/mthca_srq.c | |||
@@ -116,11 +116,16 @@ static void mthca_arbel_init_srq_context(struct mthca_dev *dev, | |||
116 | struct mthca_srq *srq, | 116 | struct mthca_srq *srq, |
117 | struct mthca_arbel_srq_context *context) | 117 | struct mthca_arbel_srq_context *context) |
118 | { | 118 | { |
119 | int logsize; | 119 | int logsize, max; |
120 | 120 | ||
121 | memset(context, 0, sizeof *context); | 121 | memset(context, 0, sizeof *context); |
122 | 122 | ||
123 | logsize = ilog2(srq->max); | 123 | /* |
124 | * Put max in a temporary variable to work around gcc bug | ||
125 | * triggered by ilog2() on sparc64. | ||
126 | */ | ||
127 | max = srq->max; | ||
128 | logsize = ilog2(max); | ||
124 | context->state_logsize_srqn = cpu_to_be32(logsize << 24 | srq->srqn); | 129 | context->state_logsize_srqn = cpu_to_be32(logsize << 24 | srq->srqn); |
125 | context->lkey = cpu_to_be32(srq->mr.ibmr.lkey); | 130 | context->lkey = cpu_to_be32(srq->mr.ibmr.lkey); |
126 | context->db_index = cpu_to_be32(srq->db_index); | 131 | context->db_index = cpu_to_be32(srq->db_index); |