Scalable CPU bitmasks
PATCH 1/1 Scalable CPU bitmasks
This patch applies to the 2.5.8-pre3 kernel. It is
essentially the same as the previous version, except that the definition of CPUMAP_SIZE is unified as suggested by [email protected].
This patch implements a scalable bitmask specifically
for tracking CPUs. It consists of two architecture-independent files, cpumap.h and cpumap.c. These files add a new datatype and supporting functions which allow for future expansion to a CPU count which is not confined to the bit-size of (unsigned long). The new datatype (cpumap_t) and supporting interfaces are optimized at compile-time according to the definition of NR_CPUS.
While systems with more than 32 processors are still
out in the future, these interfaces provide a path for gradual code migration. One of the primary goals is to provide current functionality without affecting performance. The following is a list of bitmasks that could be converted to the new datatype.
phys_cpu_present_map
cpu_initialized
wait_init_idle
cpu_online_map/cpu_present_mask
cpu_callin_map
cpu_callout_map
NOTE: The cpumap_to_ulong() and cpumap_ulong_to_cpumap() interfaces
are provided specifically for migration. If these interfaces are used when NR_CPUS is greater than the bitsize of (unsigned long), they will cause a link-time failure.
include/linux/cpumap.h new file +110 -0
@@ -0,0 +1,110 @@ +/* +* cpumap_t data type and supporting functions +* +* Copyright (c) 2002 IBM Corp. +* +* 01/25/02 Initial Version Russ Weight <[email protected]> +* 03/20/02 Move larger functions to cpumap.c Russ Weight +* +* All rights reserved. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or (at +* your option) any later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or +* NON INFRINGEMENT. See the GNU General Public License for more +* details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +* +*/ +#ifndef __LINUX_CPUMAP_H +#define __LINUX_CPUMAP_H + +#include <linux/config.h> +#include <linux/threads.h> +#include <asm/types.h> + +#define CPUMAP_SIZE ((NR_CPUS + BITS_PER_LONG - 1) / BITS_PER_LONG) + +#ifndef __ASSEMBLY__ +#include <linux/bitops.h> +typedef unsigned long cpumap_t [CPUMAP_SIZE ]; + +/* +* The following interfaces are the same regardless of CPUMAP_SIZE +*/ +#define cpumap_clear_bit clear_bit +#define cpumap_set_bit set_bit +#define cpumap_test_and_set_bit test_and_set_bit +#define cpumap_test_bit test_bit + +#if (NR_CPUS %BITS_PER_LONG ) +#define CPUMAP_FILLMASK ((1 << (NR_CPUS % BITS_PER_LONG)) -1) +#else +#define CPUMAP_FILLMASK (~0UL) +#endif + +/* +* The following macros and prototype are used to format +* a cpumap_t object for display. This function knows the +* minimum size required, which is provided as CPUMAP_BUFSIZE. +* +* The CPUMAP_BUFSIZE is an exact calcuation of the byte count +* required to display a cpumap_t object. +*/ + +#define CPUMAP_BUFSIZE (((sizeof(long) * 2) + 1) * CPUMAP_SIZE + 2) + +#if BITS_PER_LONG >32 +#define CPUMAP_FORMAT_STR "%016lx" +#else +#define CPUMAP_FORMAT_STR "%08lx" +#endif +extern char *cpumap_format (cpumap_t map,char *buf,int size); + +#if CPUMAP_SIZE ==1 +/* +* The following interfaces are optimized for the case where +* CPUMAP_SIZE==1 (i.e. a single unsigned long). The single +* CPU case falls into the CPUMAP_SIZE==1 case. +*/ +#define cpumap_to_ulong (cpumap) (cpumap[0]) +#define cpumap_ulong_to_cpumap (bitmap, cpumap) (cpumap[0] = bitmap) +#define cpumap_is_empty (cpumap) (cpumap[0] == 0) +#define cpumap_cmp_mask (map1, map2) (map1[0] == map2[0]) +#define cpumap_clear_mask (cpumap) (cpumap[0] = 0) +#define cpumap_fill (cpumap) (cpumap[0] = CPUMAP_FILLMASK) +#define cpumap_copy_mask (srcmap, destmap) (destmap[0] = srcmap[0]) +#define cpumap_and_mask (map1, map2, result) (result[0] = map1[0] & map2[0]) + +#else + +/* +* The cpumap_to_ulong() and cpumap_ulong_to_cpumap() functions +* are provided to facilitate migration to the cpumap_t datatype. +* As currently defined, they are only valid for CPUMAP_SIZE==1. +* If they are referenced when CPUMAP_SIZE > 1, then we call a +* bogus function name in order to trigger a link-time error. +*/ +extern unsigned long __bad_cpumap_to_ulong (void ); +extern void __bad_cpumap_ulong_to_cpumap (void ); +#define cpumap_to_ulong (cpumap) __bad_cpumap_to_ulong() +#define cpumap_ulong_to_cpumap (bitmap, cpumap) __bad_cpumap_ulong_to_cpumap() + +extern int cpumap_is_empty (cpumap_t map); +extern int cpumap_cmp_mask (cpumap_t map1,cpumap_t map2); +extern void cpumap_clear_mask (cpumap_t cpumap); +extern void cpumap_fill (cpumap_t cpumap); +extern void cpumap_copy_mask (cpumap_t srcmap,cpumap_t destmap); +extern void cpumap_and_mask (cpumap_t map1,cpumap_t map2,cpumap_t result); + +#endif +#endif +#endif
lib/Makefile +2 -2
@@ -8,9 +8,9 @@ L_TARGET := lib.a -export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o crc32.o rbtree.o +export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o crc32.o rbtree.o cpumap.o -obj-y := errno.o ctype.o string.o vsprintf.o brlock.o cmdline.o bust_spinlocks.o rbtree.o +obj-y := errno.o ctype.o string.o vsprintf.o brlock.o cmdline.o bust_spinlocks.o rbtree.o cpumap.o obj-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
lib/cpumap.c new file +132 -0
132 lines not on this page · raw message
Signature · 2 lines
Russ Weight ([email protected]) Linux Technology Center