You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
s390/bitops: use generic find bit functions / reimplement _left variant
Just like all other architectures we should use out-of-line find bit operations, since the inline variant bloat the size of the kernel image. And also like all other architecures we should only supply optimized variants of the __ffs, ffs, etc. primitives. Therefore this patch removes the inlined s390 find bit functions and uses the generic out-of-line variants instead. The optimization of the primitives follows with the next patch. With this patch also the functions find_first_bit_left() and find_next_bit_left() have been reimplemented, since logically, they are nothing else but a find_first_bit()/find_next_bit() implementation that use an inverted __fls() instead of __ffs(). Also the restriction that these functions only work on machines which support the "flogr" instruction is gone now. This reduces the size of the kernel image (defconfig, -march=z9-109) by 144,482 bytes. Alone the size of the function build_sched_domains() gets reduced from 7 KB to 3,5 KB. We also git rid of unused functions like find_first_bit_le()... Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
committed by
Martin Schwidefsky
parent
8e6a828566
commit
746479cdcb
@@ -99,6 +99,7 @@ config S390
|
||||
select CLONE_BACKWARDS2
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select GENERIC_CPU_DEVICES if !SMP
|
||||
select GENERIC_FIND_FIRST_BIT
|
||||
select GENERIC_SMP_IDLE_THREAD
|
||||
select GENERIC_TIME_VSYSCALL_OLD
|
||||
select HAVE_ALIGNED_STRUCT_PAGE if SLUB
|
||||
|
||||
+46
-554
File diff suppressed because it is too large
Load Diff
@@ -28,7 +28,7 @@ CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"'
|
||||
|
||||
CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w
|
||||
|
||||
obj-y := bitmap.o traps.o time.o process.o base.o early.o setup.o vtime.o
|
||||
obj-y := traps.o time.o process.o base.o early.o setup.o vtime.o
|
||||
obj-y += processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o
|
||||
obj-y += debug.o irq.o ipl.o dis.o diag.o sclp.o vdso.o
|
||||
obj-y += sysinfo.o jump_label.o lgr.o os_info.o machine_kexec.o pgm_check.o
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Bitmaps for set_bit, clear_bit, test_and_set_bit, ...
|
||||
* See include/asm/{bitops.h|posix_types.h} for details
|
||||
*
|
||||
* Copyright IBM Corp. 1999, 2009
|
||||
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>,
|
||||
*/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
const char _zb_findmap[] = {
|
||||
0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
|
||||
0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
|
||||
0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
|
||||
0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,
|
||||
0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
|
||||
0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
|
||||
0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
|
||||
0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,
|
||||
0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
|
||||
0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
|
||||
0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
|
||||
0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,
|
||||
0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
|
||||
0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
|
||||
0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
|
||||
0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,8 };
|
||||
EXPORT_SYMBOL(_zb_findmap);
|
||||
|
||||
const char _sb_findmap[] = {
|
||||
8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
|
||||
4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
|
||||
5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
|
||||
4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
|
||||
6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
|
||||
4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
|
||||
5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
|
||||
4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
|
||||
7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
|
||||
4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
|
||||
5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
|
||||
4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
|
||||
6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
|
||||
4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
|
||||
5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
|
||||
4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0 };
|
||||
EXPORT_SYMBOL(_sb_findmap);
|
||||
@@ -2,7 +2,7 @@
|
||||
# Makefile for s390-specific library files..
|
||||
#
|
||||
|
||||
lib-y += delay.o string.o uaccess_std.o uaccess_pt.o
|
||||
lib-y += delay.o string.o uaccess_std.o uaccess_pt.o find.o
|
||||
obj-$(CONFIG_32BIT) += div64.o qrnnd.o ucmpdi2.o mem32.o
|
||||
obj-$(CONFIG_64BIT) += mem64.o
|
||||
lib-$(CONFIG_64BIT) += uaccess_mvcos.o
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* MSB0 numbered special bitops handling.
|
||||
*
|
||||
* On s390x the bits are numbered:
|
||||
* |0..............63|64............127|128...........191|192...........255|
|
||||
* and on s390:
|
||||
* |0.....31|31....63|64....95|96...127|128..159|160..191|192..223|224..255|
|
||||
*
|
||||
* The reason for this bit numbering is the fact that the hardware sets bits
|
||||
* in a bitmap starting at bit 0 (MSB) and we don't want to scan the bitmap
|
||||
* from the 'wrong end'.
|
||||
*/
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/export.h>
|
||||
|
||||
unsigned long find_first_bit_left(const unsigned long *addr, unsigned long size)
|
||||
{
|
||||
const unsigned long *p = addr;
|
||||
unsigned long result = 0;
|
||||
unsigned long tmp;
|
||||
|
||||
while (size & ~(BITS_PER_LONG - 1)) {
|
||||
if ((tmp = *(p++)))
|
||||
goto found;
|
||||
result += BITS_PER_LONG;
|
||||
size -= BITS_PER_LONG;
|
||||
}
|
||||
if (!size)
|
||||
return result;
|
||||
tmp = (*p) & (~0UL << (BITS_PER_LONG - size));
|
||||
if (!tmp) /* Are any bits set? */
|
||||
return result + size; /* Nope. */
|
||||
found:
|
||||
return result + (__fls(tmp) ^ (BITS_PER_LONG - 1));
|
||||
}
|
||||
EXPORT_SYMBOL(find_first_bit_left);
|
||||
|
||||
unsigned long find_next_bit_left(const unsigned long *addr, unsigned long size,
|
||||
unsigned long offset)
|
||||
{
|
||||
const unsigned long *p = addr + (offset / BITS_PER_LONG);
|
||||
unsigned long result = offset & ~(BITS_PER_LONG - 1);
|
||||
unsigned long tmp;
|
||||
|
||||
if (offset >= size)
|
||||
return size;
|
||||
size -= result;
|
||||
offset %= BITS_PER_LONG;
|
||||
if (offset) {
|
||||
tmp = *(p++);
|
||||
tmp &= (~0UL >> offset);
|
||||
if (size < BITS_PER_LONG)
|
||||
goto found_first;
|
||||
if (tmp)
|
||||
goto found_middle;
|
||||
size -= BITS_PER_LONG;
|
||||
result += BITS_PER_LONG;
|
||||
}
|
||||
while (size & ~(BITS_PER_LONG-1)) {
|
||||
if ((tmp = *(p++)))
|
||||
goto found_middle;
|
||||
result += BITS_PER_LONG;
|
||||
size -= BITS_PER_LONG;
|
||||
}
|
||||
if (!size)
|
||||
return result;
|
||||
tmp = *p;
|
||||
found_first:
|
||||
tmp &= (~0UL << (BITS_PER_LONG - size));
|
||||
if (!tmp) /* Are any bits set? */
|
||||
return result + size; /* Nope. */
|
||||
found_middle:
|
||||
return result + (__fls(tmp) ^ (BITS_PER_LONG - 1));
|
||||
}
|
||||
EXPORT_SYMBOL(find_next_bit_left);
|
||||
Reference in New Issue
Block a user