From 3af6d494ee63e97d706178882ccd9245f1932e92 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 19 Jan 2004 05:06:28 -0800 Subject: [PATCH] fix page counting for compound pages From: "Bryan O'Sullivan" For compound pages, page_count needs to be sure to reference the head page. This affects code that plays tricks with memory mappings into userspace, which would mostly involve video drivers. --- include/linux/mm.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/mm.h b/include/linux/mm.h index 881091514f01..85a921ae376a 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -223,7 +223,6 @@ struct page { atomic_dec_and_test(&(p)->count); \ }) -#define page_count(p) atomic_read(&(p)->count) #define set_page_count(p,v) atomic_set(&(p)->count, v) #define __put_page(p) atomic_dec(&(p)->count) @@ -231,6 +230,13 @@ extern void FASTCALL(__page_cache_release(struct page *)); #ifdef CONFIG_HUGETLB_PAGE +static inline int page_count(struct page *p) +{ + if (PageCompound(p)) + p = (struct page *)p->lru.next; + return atomic_read(&(p)->count); +} + static inline void get_page(struct page *page) { if (PageCompound(page)) @@ -257,6 +263,8 @@ static inline void put_page(struct page *page) #else /* CONFIG_HUGETLB_PAGE */ +#define page_count(p) atomic_read(&(p)->count) + static inline void get_page(struct page *page) { atomic_inc(&page->count); -- cgit v1.2.3 From 6283f86ec40c482d69acb720451cf69098009b9d Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 19 Jan 2004 05:07:14 -0800 Subject: [PATCH] ext2: s_next_generation locking There is no locking around the increment of this per-filesystem counter. Create a new lock, just for this. --- fs/ext2/ialloc.c | 2 ++ fs/ext2/super.c | 1 + include/linux/ext2_fs_sb.h | 1 + 3 files changed, 4 insertions(+) (limited to 'include/linux') diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c index 20d396902c25..95ad61fc80b7 100644 --- a/fs/ext2/ialloc.c +++ b/fs/ext2/ialloc.c @@ -599,7 +599,9 @@ got: ei->i_dir_start_lookup = 0; ei->i_state = EXT2_STATE_NEW; ext2_set_inode_flags(inode); + spin_lock(&sbi->s_next_gen_lock); inode->i_generation = sbi->s_next_generation++; + spin_unlock(&sbi->s_next_gen_lock); insert_inode_hash(inode); if (DQUOT_ALLOC_INODE(inode)) { diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 410f95252bdb..576951e2bbdd 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -809,6 +809,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) } sbi->s_gdb_count = db_count; get_random_bytes(&sbi->s_next_generation, sizeof(u32)); + spin_lock_init(&sbi->s_next_gen_lock); /* * set up enough so that it can read an inode */ diff --git a/include/linux/ext2_fs_sb.h b/include/linux/ext2_fs_sb.h index 13178c16c7ea..4eda0ed76a48 100644 --- a/include/linux/ext2_fs_sb.h +++ b/include/linux/ext2_fs_sb.h @@ -45,6 +45,7 @@ struct ext2_sb_info { int s_desc_per_block_bits; int s_inode_size; int s_first_ino; + spinlock_t s_next_gen_lock; u32 s_next_generation; unsigned long s_dir_count; u8 *s_debts; -- cgit v1.2.3 From 546e1d8baf586ecc701280aa328df7251d70ddb8 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 19 Jan 2004 05:07:24 -0800 Subject: [PATCH] ext3: s_next_generation fixes - Add missing locking around s_next_generation increment - Correctly set the initial value of s_next_generation. --- fs/ext3/ialloc.c | 6 ++++-- fs/ext3/super.c | 3 +++ include/linux/ext3_fs_sb.h | 1 + 3 files changed, 8 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c index 13f61fc9e85a..c0c206fea391 100644 --- a/fs/ext3/ialloc.c +++ b/fs/ext3/ialloc.c @@ -446,8 +446,8 @@ struct inode *ext3_new_inode(handle_t *handle, struct inode * dir, int mode) return ERR_PTR(-ENOMEM); ei = EXT3_I(inode); - es = EXT3_SB(sb)->s_es; sbi = EXT3_SB(sb); + es = sbi->s_es; if (S_ISDIR(mode)) { if (test_opt (sb, OLDALLOC)) group = find_group_dir(sb, dir); @@ -591,7 +591,9 @@ got: if (IS_DIRSYNC(inode)) handle->h_sync = 1; insert_inode_hash(inode); - inode->i_generation = EXT3_SB(sb)->s_next_generation++; + spin_lock(&sbi->s_next_gen_lock); + inode->i_generation = sbi->s_next_generation++; + spin_unlock(&sbi->s_next_gen_lock); ei->i_state = EXT3_STATE_NEW; diff --git a/fs/ext3/super.c b/fs/ext3/super.c index e2b4a68ccd1a..ea5cfb9ce3c7 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "xattr.h" #include "acl.h" @@ -1287,6 +1288,8 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) goto failed_mount2; } sbi->s_gdb_count = db_count; + get_random_bytes(&sbi->s_next_generation, sizeof(u32)); + spin_lock_init(&sbi->s_next_gen_lock); /* * set up enough so that it can read an inode */ diff --git a/include/linux/ext3_fs_sb.h b/include/linux/ext3_fs_sb.h index e9b4012cc776..590fd69ec045 100644 --- a/include/linux/ext3_fs_sb.h +++ b/include/linux/ext3_fs_sb.h @@ -49,6 +49,7 @@ struct ext3_sb_info { int s_desc_per_block_bits; int s_inode_size; int s_first_ino; + spinlock_t s_next_gen_lock; u32 s_next_generation; u32 s_hash_seed[4]; int s_def_hash_version; -- cgit v1.2.3 From 8e1b379f569672d4b23fe72075fb7207d251382c Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 19 Jan 2004 05:07:59 -0800 Subject: [PATCH] Fix weird placement of inline From: Jesper Juhl I'm compiling 2.6.1-rc1-mm1 with "-W -Wall" to look for potential problems and minor stuff to clean up. One of the things that enabling the extra warnings turn up is errors about the placement of the inline keyword. --- arch/i386/kernel/efi.c | 4 ++-- include/linux/efi.h | 4 ++-- kernel/posix-timers.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/arch/i386/kernel/efi.c b/arch/i386/kernel/efi.c index 310090d060ec..43a40b791ec4 100644 --- a/arch/i386/kernel/efi.c +++ b/arch/i386/kernel/efi.c @@ -174,7 +174,7 @@ phys_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) return status; } -int inline efi_set_rtc_mmss(unsigned long nowtime) +inline int efi_set_rtc_mmss(unsigned long nowtime) { int real_seconds, real_minutes; efi_status_t status; @@ -207,7 +207,7 @@ int inline efi_set_rtc_mmss(unsigned long nowtime) * services have been remapped, therefore, we'll need to call in physical * mode. Note, this call isn't used later, so mark it __init. */ -unsigned long inline __init efi_get_time(void) +inline unsigned long __init efi_get_time(void) { efi_status_t status; efi_time_t eft; diff --git a/include/linux/efi.h b/include/linux/efi.h index 86e9d2ebb5eb..d6cac7ce314d 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -297,8 +297,8 @@ extern u64 efi_mem_attributes (unsigned long phys_addr); extern void efi_initialize_iomem_resources(struct resource *code_resource, struct resource *data_resource); extern efi_status_t phys_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc); -extern unsigned long inline __init efi_get_time(void); -extern int inline __init efi_set_rtc_mmss(unsigned long nowtime); +extern inline unsigned long __init efi_get_time(void); +extern inline int __init efi_set_rtc_mmss(unsigned long nowtime); extern struct efi_memory_map memmap; #ifdef CONFIG_EFI diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index 431002eebb0a..c06a7dc25da9 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c @@ -574,7 +574,7 @@ static struct k_itimer * lock_timer(timer_t timer_id, unsigned long *flags) * it is the same as a requeue pending timer WRT to what we should * report. */ -void inline +inline void do_timer_gettime(struct k_itimer *timr, struct itimerspec *cur_setting) { unsigned long expires; -- cgit v1.2.3 From 490d4075866f7991dea333e020415fcfaaf1da9f Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 19 Jan 2004 05:10:30 -0800 Subject: [PATCH] Simplify node/zone field in page->flags From: Matthew Dobson This patch does the following: 1) Rename ZONE_SHIFT to NODEZONE_SHIFT. This value is the number of bits to shift page->flags to get the node/zone part of the bitfield. 2) Add a macro called NODEZONE which takes a node number and zone number and returns a 'nodezone', a bitshifted composition of the two. 3) Create page_zonenum & page_nodenum, inline functions to return the node/zone a page belongs to with some simple bit twiddling, no pointer dereferences necessary. 4) Modify page_zone() and set_page_zone() to use the new NODEZONE_SHIFT. 5) Modify memmap_init_zone() & free_area_init_core() to use the new NODEZONE macros. 6) Fix up some comments to reflect the above changes. --- include/linux/mm.h | 24 +++++++++++++++++------- include/linux/mmzone.h | 15 +++++++++++---- mm/page_alloc.c | 6 +++--- 3 files changed, 31 insertions(+), 14 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mm.h b/include/linux/mm.h index 85a921ae376a..42f5c2df91d1 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -330,23 +330,33 @@ static inline void put_page(struct page *page) /* * The zone field is never updated after free_area_init_core() * sets it, so none of the operations on it need to be atomic. - * We'll have up to log2(MAX_NUMNODES * MAX_NR_ZONES) zones - * total, so we use NODES_SHIFT here to get enough bits. + * We'll have up to (MAX_NUMNODES * MAX_NR_ZONES) zones total, + * so we use (MAX_NODES_SHIFT + MAX_ZONES_SHIFT) here to get enough bits. */ -#define ZONE_SHIFT (BITS_PER_LONG - NODES_SHIFT - MAX_NR_ZONES_SHIFT) +#define NODEZONE_SHIFT (BITS_PER_LONG - MAX_NODES_SHIFT - MAX_ZONES_SHIFT) +#define NODEZONE(node, zone) ((node << ZONES_SHIFT) | zone) + +static inline unsigned long page_zonenum(struct page *page) +{ + return (page->flags >> NODEZONE_SHIFT) & (~(~0UL << ZONES_SHIFT)); +} +static inline unsigned long page_nodenum(struct page *page) +{ + return (page->flags >> (NODEZONE_SHIFT + ZONES_SHIFT)); +} struct zone; extern struct zone *zone_table[]; static inline struct zone *page_zone(struct page *page) { - return zone_table[page->flags >> ZONE_SHIFT]; + return zone_table[page->flags >> NODEZONE_SHIFT]; } -static inline void set_page_zone(struct page *page, unsigned long zone_num) +static inline void set_page_zone(struct page *page, unsigned long nodezone_num) { - page->flags &= ~(~0UL << ZONE_SHIFT); - page->flags |= zone_num << ZONE_SHIFT; + page->flags &= ~(~0UL << NODEZONE_SHIFT); + page->flags |= nodezone_num << NODEZONE_SHIFT; } #ifndef CONFIG_DISCONTIGMEM diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index a089e01dad03..9fa4ffb2675c 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -160,8 +160,8 @@ struct zone { #define ZONE_NORMAL 1 #define ZONE_HIGHMEM 2 -#define MAX_NR_ZONES 3 /* Sync this with MAX_NR_ZONES_SHIFT */ -#define MAX_NR_ZONES_SHIFT 2 /* ceil(log2(MAX_NR_ZONES)) */ +#define MAX_NR_ZONES 3 /* Sync this with ZONES_SHIFT */ +#define ZONES_SHIFT 2 /* ceil(log2(MAX_NR_ZONES)) */ #define GFP_ZONEMASK 0x03 @@ -303,7 +303,7 @@ int min_free_kbytes_sysctl_handler(struct ctl_table *, int, struct file *, extern struct pglist_data contig_page_data; #define NODE_DATA(nid) (&contig_page_data) #define NODE_MEM_MAP(nid) mem_map -#define MAX_NODES_SHIFT 0 +#define MAX_NODES_SHIFT 1 #else /* CONFIG_DISCONTIGMEM */ @@ -311,7 +311,7 @@ extern struct pglist_data contig_page_data; #if BITS_PER_LONG == 32 /* - * with 32 bit flags field, page->zone is currently 8 bits. + * with 32 bit page->flags field, we reserve 8 bits for node/zone info. * there are 3 zones (2 bits) and this leaves 8-2=6 bits for nodes. */ #define MAX_NODES_SHIFT 6 @@ -328,6 +328,13 @@ extern struct pglist_data contig_page_data; #error NODES_SHIFT > MAX_NODES_SHIFT #endif +/* There are currently 3 zones: DMA, Normal & Highmem, thus we need 2 bits */ +#define MAX_ZONES_SHIFT 2 + +#if ZONES_SHIFT > MAX_ZONES_SHIFT +#error ZONES_SHIFT > MAX_ZONES_SHIFT +#endif + extern DECLARE_BITMAP(node_online_map, MAX_NUMNODES); extern DECLARE_BITMAP(memblk_online_map, MAX_NR_MEMBLKS); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index c3de7ee44d6e..c36a51318004 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -50,7 +50,7 @@ EXPORT_SYMBOL(nr_swap_pages); * Used by page_zone() to look up the address of the struct zone whose * id is encoded in the upper bits of page->flags */ -struct zone *zone_table[MAX_NR_ZONES*MAX_NUMNODES]; +struct zone *zone_table[1 << (ZONES_SHIFT + NODES_SHIFT)]; EXPORT_SYMBOL(zone_table); static char *zone_names[MAX_NR_ZONES] = { "DMA", "Normal", "HighMem" }; @@ -1212,7 +1212,7 @@ void __init memmap_init_zone(struct page *start, unsigned long size, int nid, struct page *page; for (page = start; page < (start + size); page++) { - set_page_zone(page, nid * MAX_NR_ZONES + zone); + set_page_zone(page, NODEZONE(nid, zone)); set_page_count(page, 0); SetPageReserved(page); INIT_LIST_HEAD(&page->list); @@ -1253,7 +1253,7 @@ static void __init free_area_init_core(struct pglist_data *pgdat, unsigned long size, realsize; unsigned long batch; - zone_table[nid * MAX_NR_ZONES + j] = zone; + zone_table[NODEZONE(nid, j)] = zone; realsize = size = zones_size[j]; if (zholes_size) realsize -= zholes_size[j]; -- cgit v1.2.3 From 21c7c9d2356d2ebe5c47f29aec33ecc040f418ad Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 19 Jan 2004 05:10:39 -0800 Subject: [PATCH] Identify RADEON Yd in radeonfb From: Bernardo Innocenti Identify a recent Radeon video card in radeonfb. --- drivers/video/radeonfb.c | 2 ++ include/linux/pci_ids.h | 1 + 2 files changed, 3 insertions(+) (limited to 'include/linux') diff --git a/drivers/video/radeonfb.c b/drivers/video/radeonfb.c index 989f3d457bda..da1a38bfa768 100644 --- a/drivers/video/radeonfb.c +++ b/drivers/video/radeonfb.c @@ -114,6 +114,7 @@ enum radeon_chips { RADEON_Ie, RADEON_If, RADEON_Ig, + RADEON_Yd, RADEON_Ld, RADEON_Le, RADEON_Lf, @@ -207,6 +208,7 @@ static struct pci_device_id radeonfb_pci_table[] = { { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ie, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ie}, { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_If, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_If}, { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ig, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ig}, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Yd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Yd}, { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ld, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ld}, { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Le, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Le}, { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Lf, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Lf}, diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 86d2bbccd9ea..4dba6ec06e3a 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -291,6 +291,7 @@ #define PCI_DEVICE_ID_ATI_RADEON_Ig 0x4967 /* Radeon RV280 (9200) */ #define PCI_DEVICE_ID_ATI_RADEON_Y_ 0x5960 +#define PCI_DEVICE_ID_ATI_RADEON_Yd 0x5964 /* Radeon R300 (9500) */ #define PCI_DEVICE_ID_ATI_RADEON_AD 0x4144 /* Radeon R300 (9700) */ -- cgit v1.2.3 From f1933a6dd8c813d5f7482f4fc48dd343003a10de Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 19 Jan 2004 05:11:34 -0800 Subject: [PATCH] vmscan: initialize zone->{prev,temp}_priority From: Nikita Danilov This patch initializes zone->{prev,temp}_priority to DEF_PRIORITY. Otherwise they are left zeroed, and first run of VM scanner thinks that zones are under enormous stress. --- include/linux/mmzone.h | 7 +++++++ mm/page_alloc.c | 2 ++ mm/vmscan.c | 7 ------- 3 files changed, 9 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 9fa4ffb2675c..66cbaa36d878 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -165,6 +165,13 @@ struct zone { #define GFP_ZONEMASK 0x03 +/* + * The "priority" of VM scanning is how much of the queues we will scan in one + * go. A value of 12 for DEF_PRIORITY implies that we will scan 1/4096th of the + * queues ("queue_length >> 12") during an aging round. + */ +#define DEF_PRIORITY 12 + /* * One allocation request operates on a zonelist. A zonelist * is a list of zones, the first one is the 'goal' of the diff --git a/mm/page_alloc.c b/mm/page_alloc.c index c36a51318004..b2a185f246d4 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1266,6 +1266,8 @@ static void __init free_area_init_core(struct pglist_data *pgdat, zone->zone_pgdat = pgdat; zone->free_pages = 0; + zone->temp_priority = zone->prev_priority = DEF_PRIORITY; + /* * The per-cpu-pages pools are set to around 1000th of the * size of the zone. But no more than 1/4 of a meg - there's diff --git a/mm/vmscan.c b/mm/vmscan.c index bb27edc29afd..dcb7dc0f176d 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -37,13 +37,6 @@ #include -/* - * The "priority" of VM scanning is how much of the queues we will scan in one - * go. A value of 12 for DEF_PRIORITY implies that we will scan 1/4096th of the - * queues ("queue_length >> 12") during an aging round. - */ -#define DEF_PRIORITY 12 - /* * From 0 .. 100. Higher means more swappy. */ -- cgit v1.2.3 From eb4f6fb91be878c1acd727d62abb600b77b631fd Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 19 Jan 2004 05:12:38 -0800 Subject: [PATCH] Fix statically declare FIXMAPs From: Anton Blanchard , me. Two uses of the FIXADDR_USER_START/END things are problematic: a) ppc64 wants the FIXADDR area to be at a different location on 32bit and 64bit tasks. On 32bit we want it just below 4GB but that gets in the way on 64bit. By putting both right at -(some small amount) we can also use some ppc tricks to get there real quickly (single instruction branches). b) We assume that FIXADDR_USER_START and FIXADDR_USER_END are constants. This breaks the UML build. Fixes: - Call it all gate. We currently have half the stuff called fixmap and the other gate, lets be consistent. - Create in_gate_area(), get_gate_vma() and use it in both places - Provide defaults for in_gate_area/get_gate_vma, allowing an arch to override it. (I used CONFIG_* but am open to better suggestions here) - The /proc/pid/maps vma wasnt marked readable but the get_user vma was. That sounds suspicious to me, they are now both the same VMA and so have the same (read,exec) permissions --- fs/proc/task_mmu.c | 26 ++++++-------------------- include/linux/mm.h | 28 ++++++++++++++++++++++++++++ mm/memory.c | 37 ++++++++++++++++++++----------------- 3 files changed, 54 insertions(+), 37 deletions(-) (limited to 'include/linux') diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 739ca9f198e9..1a7440ae3902 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -76,22 +76,6 @@ int task_statm(struct mm_struct *mm, int *shared, int *text, return size; } -#ifdef AT_SYSINFO_EHDR - -static struct vm_area_struct gate_vmarea = { - /* Do _not_ mark this area as readable, cuz not the entire range may be readable - (e.g., due to execute-only pages or holes) and the tools that read - /proc/PID/maps should read the interesting bits from the gate-DSO file - instead. */ - .vm_start = FIXADDR_USER_START, - .vm_end = FIXADDR_USER_END -}; - -# define gate_map() &gate_vmarea -#else -# define gate_map() NULL -#endif - static int show_map(struct seq_file *m, void *v) { struct vm_area_struct *map = v; @@ -146,15 +130,16 @@ static void *m_start(struct seq_file *m, loff_t *pos) up_read(&mm->mmap_sem); mmput(mm); if (l == -1) - map = gate_map(); + map = get_gate_vma(task); } return map; } static void m_stop(struct seq_file *m, void *v) { + struct task_struct *task = m->private; struct vm_area_struct *map = v; - if (map && map != gate_map()) { + if (map && map != get_gate_vma(task)) { struct mm_struct *mm = map->vm_mm; up_read(&mm->mmap_sem); mmput(mm); @@ -163,13 +148,14 @@ static void m_stop(struct seq_file *m, void *v) static void *m_next(struct seq_file *m, void *v, loff_t *pos) { + struct task_struct *task = m->private; struct vm_area_struct *map = v; (*pos)++; if (map->vm_next) return map->vm_next; m_stop(m, v); - if (map != gate_map()) - return gate_map(); + if (map != get_gate_vma(task)) + return get_gate_vma(task); return NULL; } diff --git a/include/linux/mm.h b/include/linux/mm.h index 42f5c2df91d1..3ecd3d633c5f 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -642,5 +642,33 @@ kernel_map_pages(struct page *page, int numpages, int enable) } #endif +#ifndef CONFIG_ARCH_GATE_AREA +#ifdef AT_SYSINFO_EHDR +static inline int in_gate_area(struct task_struct *task, unsigned long addr) +{ + if ((addr >= FIXADDR_USER_START) && (addr < FIXADDR_USER_END)) + return 1; + else + return 0; +} + +extern struct vm_area_struct gate_vma; +static inline struct vm_area_struct *get_gate_vma(struct task_struct *tsk) +{ + return &gate_vma; +} +#else +static inline int in_gate_area(struct task_struct *task, unsigned long addr) +{ + return 0; +} + +static inline struct vm_area_struct *get_gate_vma(struct task_struct *tsk) +{ + return NULL; +} +#endif +#endif + #endif /* __KERNEL__ */ #endif /* _LINUX_MM_H */ diff --git a/mm/memory.c b/mm/memory.c index f1c49a218663..d0c834a8ce97 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -704,25 +705,13 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, struct vm_area_struct * vma; vma = find_extend_vma(mm, start); - -#ifdef FIXADDR_USER_START - if (!vma && - start >= FIXADDR_USER_START && start < FIXADDR_USER_END) { - static struct vm_area_struct fixmap_vma = { - /* Catch users - if there are any valid - ones, we can make this be "&init_mm" or - something. */ - .vm_mm = NULL, - .vm_start = FIXADDR_USER_START, - .vm_end = FIXADDR_USER_END, - .vm_page_prot = PAGE_READONLY, - .vm_flags = VM_READ | VM_EXEC, - }; + if (!vma && in_gate_area(tsk, start)) { unsigned long pg = start & PAGE_MASK; + struct vm_area_struct *gate_vma = get_gate_vma(tsk); pgd_t *pgd; pmd_t *pmd; pte_t *pte; - if (write) /* user fixmap pages are read-only */ + if (write) /* user gate pages are read-only */ return i ? : -EFAULT; pgd = pgd_offset_k(pg); if (!pgd) @@ -738,13 +727,12 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, get_page(pages[i]); } if (vmas) - vmas[i] = &fixmap_vma; + vmas[i] = gate_vma; i++; start += PAGE_SIZE; len--; continue; } -#endif if (!vma || (pages && (vma->vm_flags & VM_IO)) || !(flags & vma->vm_flags)) @@ -1699,3 +1687,18 @@ struct page * vmalloc_to_page(void * vmalloc_addr) } EXPORT_SYMBOL(vmalloc_to_page); + +#if !defined(CONFIG_ARCH_GATE_AREA) && defined(AT_SYSINFO_EHDR) +struct vm_area_struct gate_vma; + +static int __init gate_vma_init(void) +{ + gate_vma.vm_mm = NULL; + gate_vma.vm_start = FIXADDR_USER_START; + gate_vma.vm_end = FIXADDR_USER_END; + gate_vma.vm_page_prot = PAGE_READONLY; + gate_vma.vm_flags = 0; + return 0; +} +__initcall(gate_vma_init); +#endif -- cgit v1.2.3 From 7766a93b9d7b27c48c70abbd36fdd64cfec30023 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 19 Jan 2004 05:12:56 -0800 Subject: [PATCH] Add bdev private field From: Christoph Hellwig Currently xfs has a per-bdev (and XFS filesystem uses up to three underlying block devices) object that Al complained about loudly that it should be gone. But for that to happen without rewriting half of XFS (and changing layering in a way that we don't really want) we need an additional fs-private variable in struct block_device. --- include/linux/fs.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/linux') diff --git a/include/linux/fs.h b/include/linux/fs.h index fd3c87c86d6f..7d9154665d9b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -353,6 +353,13 @@ struct block_device { int bd_invalidated; struct gendisk * bd_disk; struct list_head bd_list; + /* + * Private data. You must have bd_claim'ed the block_device + * to use this. NOTE: bd_claim allows an owner to claim + * the same device multiple times, the owner must take special + * care to not mess up bd_private for that case. + */ + unsigned long bd_private; }; /* -- cgit v1.2.3 From d91341a903501da6249a38f0c35528f176b5f533 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 19 Jan 2004 05:13:05 -0800 Subject: [PATCH] ext3: fix determination of inode journalling mode The test for whether an inode is using journalled, ordered or writeback data is incorrect and can lead to ext3_set_aops() giving the inode the wrong set of address_space_operations. Fix. (Spotted by Jan Kara). --- include/linux/ext3_jbd.h | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ext3_jbd.h b/include/linux/ext3_jbd.h index 50caf6875ba4..a3555b48cccb 100644 --- a/include/linux/ext3_jbd.h +++ b/include/linux/ext3_jbd.h @@ -221,13 +221,24 @@ static inline int ext3_should_journal_data(struct inode *inode) static inline int ext3_should_order_data(struct inode *inode) { - return (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA); + if (!S_ISREG(inode->i_mode)) + return 0; + if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) + return 0; + if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA) + return 1; + return 0; } static inline int ext3_should_writeback_data(struct inode *inode) { - return !ext3_should_journal_data(inode) && - !ext3_should_order_data(inode); + if (!S_ISREG(inode->i_mode)) + return 0; + if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) + return 0; + if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA) + return 1; + return 0; } #endif /* _LINUX_EXT3_JBD_H */ -- cgit v1.2.3 From ce65cade5848263c483eda1b7ffe9ed5a01a0c8f Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 19 Jan 2004 05:13:14 -0800 Subject: [PATCH] Arrange for EFI-related code to be compiled away From: David Mosberger There is some EFI-related code which is present in the ia64 build but is not needed: variable efi_enabled is always zero. The patch fiddles with the efi_enabled definition to arrange for `efi_enabled' to be constant zero or constant one in those situations where this can be guaranteed. --- arch/ia64/kernel/setup.c | 4 ---- include/linux/efi.h | 12 ++++++++++-- 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 1af40201af85..99f5f315fbc3 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -55,10 +55,6 @@ # error "struct cpuinfo_ia64 too big!" #endif -#ifdef CONFIG_EFI -int efi_enabled = 1; -#endif - #ifdef CONFIG_SMP unsigned long __per_cpu_offset[NR_CPUS]; EXPORT_SYMBOL(__per_cpu_offset); diff --git a/include/linux/efi.h b/include/linux/efi.h index d6cac7ce314d..a1764b1fb106 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -301,10 +301,18 @@ extern inline unsigned long __init efi_get_time(void); extern inline int __init efi_set_rtc_mmss(unsigned long nowtime); extern struct efi_memory_map memmap; +/* + * We play games with efi_enabled so that the compiler will, if possible, remove + * EFI-related code altogether. + */ #ifdef CONFIG_EFI -extern int efi_enabled; +# ifdef CONFIG_X86 + extern int efi_enabled; +# else +# define efi_enabled 1 +# endif #else -#define efi_enabled 0 +# define efi_enabled 0 #endif /* -- cgit v1.2.3 From fd2ac4b289d00952ee14782ed5d282dcb0191a6c Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 19 Jan 2004 05:13:24 -0800 Subject: [PATCH] make gcc 3.4 compilation work From: David Mosberger With gcc-3.4 we need "attribute((used))" declarations to get "make modules_install" to work. Otherwise these sections get dropped from the final image (I assume). --- include/linux/module.h | 3 +++ include/linux/moduleparam.h | 1 + scripts/modpost.c | 1 + 3 files changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/module.h b/include/linux/module.h index 13ff244afdbf..c0418e47a296 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -60,6 +60,7 @@ search_extable(const struct exception_table_entry *first, #define __module_cat(a,b) ___module_cat(a,b) #define __MODULE_INFO(tag, name, info) \ static const char __module_cat(name,__LINE__)[] \ + __attribute_used__ \ __attribute__((section(".modinfo"),unused)) = __stringify(tag) "=" info #define MODULE_GENERIC_TABLE(gtype,name) \ @@ -142,6 +143,7 @@ void *__symbol_get_gpl(const char *symbol); #define __CRC_SYMBOL(sym, sec) \ extern void *__crc_##sym __attribute__((weak)); \ static const unsigned long __kcrctab_##sym \ + __attribute_used__ \ __attribute__((section("__kcrctab" sec), unused)) \ = (unsigned long) &__crc_##sym; #else @@ -155,6 +157,7 @@ void *__symbol_get_gpl(const char *symbol); __attribute__((section("__ksymtab_strings"))) \ = MODULE_SYMBOL_PREFIX #sym; \ static const struct kernel_symbol __ksymtab_##sym \ + __attribute_used__ \ __attribute__((section("__ksymtab" sec), unused)) \ = { (unsigned long)&sym, __kstrtab_##sym } diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h index 0a5becbed774..cbca00722b5c 100644 --- a/include/linux/moduleparam.h +++ b/include/linux/moduleparam.h @@ -52,6 +52,7 @@ struct kparam_array #define __module_param_call(prefix, name, set, get, arg, perm) \ static char __param_str_##name[] __initdata = prefix #name; \ static struct kernel_param const __param_##name \ + __attribute_used__ \ __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \ = { __param_str_##name, perm, set, get, arg } diff --git a/scripts/modpost.c b/scripts/modpost.c index 0b6d7dfffab6..7e6a4bb035a7 100644 --- a/scripts/modpost.c +++ b/scripts/modpost.c @@ -446,6 +446,7 @@ add_versions(struct buffer *b, struct module *mod) buf_printf(b, "\n"); buf_printf(b, "static const struct modversion_info ____versions[]\n"); + buf_printf(b, "__attribute_used__\n"); buf_printf(b, "__attribute__((section(\"__versions\"))) = {\n"); for (s = mod->unres; s; s = s->next) { -- cgit v1.2.3 From f598fb8d97c017bd343a75a3fe906e7d45918d5e Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 19 Jan 2004 05:13:35 -0800 Subject: [PATCH] if ... BUG() -> BUG_ON() From: Adrian Bunk four months ago, Rolf Eike Beer sent a patch against 2.6.0-test5-bk1 that converted several if ... BUG() to BUG_ON() This might in some cases result in slightly faster code because BUG_ON() uses unlikely(). --- include/asm-alpha/topology.h | 3 +-- include/asm-arm/arch-ebsa285/io.h | 6 ++---- include/asm-arm/arch-nexuspci/io.h | 3 +-- include/asm-mips/dma-mapping.h | 12 ++++-------- include/asm-mips/pci.h | 3 +-- include/asm-parisc/mmu_context.h | 5 ++--- include/asm-parisc/tlbflush.h | 2 +- include/asm-ppc/highmem.h | 9 +++------ include/asm-ppc/pci.h | 9 +++------ include/asm-ppc64/pci.h | 6 ++---- include/asm-ppc64/topology.h | 3 +-- include/asm-s390/idals.h | 6 ++---- include/asm-sh/spinlock.h | 3 +-- include/asm-sparc64/floppy.h | 5 ++--- include/asm-sparc64/tlbflush.h | 3 +-- include/asm-x86_64/pgalloc.h | 9 +++------ include/asm-x86_64/spinlock.h | 18 ++++++------------ include/linux/bio.h | 3 +-- include/linux/buffer_head.h | 3 +-- include/linux/dcache.h | 3 +-- include/linux/highmem.h | 3 +-- include/linux/netdevice.h | 4 ++-- include/linux/nfs_fs.h | 3 +-- include/linux/quotaops.h | 6 ++---- include/linux/smp_lock.h | 3 +-- include/net/sock.h | 4 ++-- include/net/tcp.h | 2 +- include/rxrpc/call.h | 3 +-- include/rxrpc/connection.h | 3 +-- include/rxrpc/message.h | 3 +-- include/rxrpc/peer.h | 3 +-- include/rxrpc/transport.h | 3 +-- 32 files changed, 54 insertions(+), 100 deletions(-) (limited to 'include/linux') diff --git a/include/asm-alpha/topology.h b/include/asm-alpha/topology.h index 742b68802fd0..dbdb0d4f90e1 100644 --- a/include/asm-alpha/topology.h +++ b/include/asm-alpha/topology.h @@ -16,8 +16,7 @@ static inline int cpu_to_node(int cpu) node = alpha_mv.cpuid_to_nid(cpu); #ifdef DEBUG_NUMA - if (node < 0) - BUG(); + BUG_ON(node < 0); #endif return node; diff --git a/include/asm-arm/arch-ebsa285/io.h b/include/asm-arm/arch-ebsa285/io.h index aac50402bc1b..8511b2ce534f 100644 --- a/include/asm-arm/arch-ebsa285/io.h +++ b/include/asm-arm/arch-ebsa285/io.h @@ -27,15 +27,13 @@ static inline unsigned long ___mem_pci(unsigned long a) { - if (a <= 0xc0000000 || a >= 0xe0000000) - BUG(); + BUG_ON(a <= 0xc0000000 || a >= 0xe0000000); return a; } static inline unsigned long ___mem_isa(unsigned long a) { - if (a >= 16*1048576) - BUG(); + BUG_ON(a >= 16*1048576); return PCIMEM_BASE + a; } #define __mem_pci(a) ___mem_pci((unsigned long)(a)) diff --git a/include/asm-arm/arch-nexuspci/io.h b/include/asm-arm/arch-nexuspci/io.h index 8afa61e6acba..181bdb5988df 100644 --- a/include/asm-arm/arch-nexuspci/io.h +++ b/include/asm-arm/arch-nexuspci/io.h @@ -28,8 +28,7 @@ static inline unsigned long ___mem_pci(unsigned long a) static inline unsigned long ___mem_isa(unsigned long a) { - if (a >= 16*1048576) - BUG(); + BUG_ON(a >= 16*1048576); return PCIMEM_BASE + a; } #define __mem_pci(a) ___mem_pci((unsigned long)(a)) diff --git a/include/asm-mips/dma-mapping.h b/include/asm-mips/dma-mapping.h index 7b6254324cc9..d72e991e4a2b 100644 --- a/include/asm-mips/dma-mapping.h +++ b/include/asm-mips/dma-mapping.h @@ -124,8 +124,7 @@ dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, for (i = 0; i < nhwentries; i++, sg++) { unsigned long addr; - if (!sg->page) - BUG(); + BUG_ON(!sg->page); addr = (unsigned long) page_address(sg->page); if (addr) @@ -139,8 +138,7 @@ dma_sync_single(struct device *dev, dma_addr_t dma_handle, size_t size, { unsigned long addr; - if (direction == DMA_NONE) - BUG(); + BUG_ON(direction == DMA_NONE); addr = baddr_to_bus(hwdev->bus, dma_handle) + PAGE_OFFSET; dma_cache_wback_inv(addr, size); @@ -153,8 +151,7 @@ dma_sync_single_range(struct device *dev, dma_addr_t dma_handle, { unsigned long addr; - if (direction == DMA_NONE) - BUG(); + BUG_ON(direction == DMA_NONE); addr = baddr_to_bus(hwdev->bus, dma_handle) + PAGE_OFFSET; dma_cache_wback_inv(addr, size); @@ -168,8 +165,7 @@ dma_sync_sg(struct device *dev, struct scatterlist *sg, int nelems, int i; #endif - if (direction == DMA_NONE) - BUG(); + BUG_ON(direction == DMA_NONE); /* Make sure that gcc doesn't leave the empty loop body. */ #ifdef CONFIG_NONCOHERENT_IO diff --git a/include/asm-mips/pci.h b/include/asm-mips/pci.h index 56e01db6f45d..cd96c958408f 100644 --- a/include/asm-mips/pci.h +++ b/include/asm-mips/pci.h @@ -113,8 +113,7 @@ static inline void pci_dac_dma_sync_single(struct pci_dev *pdev, { unsigned long addr; - if (direction == PCI_DMA_NONE) - BUG(); + BUG_ON(direction == PCI_DMA_NONE); addr = baddr_to_bus(pdev->bus, dma_addr) + PAGE_OFFSET; dma_cache_wback_inv(addr, len); diff --git a/include/asm-parisc/mmu_context.h b/include/asm-parisc/mmu_context.h index 6327156282f2..9c05836239a2 100644 --- a/include/asm-parisc/mmu_context.h +++ b/include/asm-parisc/mmu_context.h @@ -19,8 +19,7 @@ extern void free_sid(unsigned long); static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm) { - if (atomic_read(&mm->mm_users) != 1) - BUG(); + BUG_ON(atomic_read(&mm->mm_users) != 1); mm->context = alloc_sid(); return 0; @@ -64,7 +63,7 @@ static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next) * already, so we should be OK. */ - if (next == &init_mm) BUG(); /* Should never happen */ + BUG_ON(next == &init_mm); /* Should never happen */ if (next->context == 0) next->context = alloc_sid(); diff --git a/include/asm-parisc/tlbflush.h b/include/asm-parisc/tlbflush.h index a5b731f654cb..86ba2c7ec6f3 100644 --- a/include/asm-parisc/tlbflush.h +++ b/include/asm-parisc/tlbflush.h @@ -27,7 +27,7 @@ extern void flush_tlb_all(void); static inline void flush_tlb_mm(struct mm_struct *mm) { - if (mm == &init_mm) BUG(); /* Should never happen */ + BUG_ON(mm == &init_mm); /* Should never happen */ #ifdef CONFIG_SMP flush_tlb_all(); diff --git a/include/asm-ppc/highmem.h b/include/asm-ppc/highmem.h index c13b4e495519..ca057b43a2ee 100644 --- a/include/asm-ppc/highmem.h +++ b/include/asm-ppc/highmem.h @@ -63,8 +63,7 @@ static inline void *kmap(struct page *page) static inline void kunmap(struct page *page) { - if (in_interrupt()) - BUG(); + BUG_ON(in_interrupt()); if (page < highmem_start_page) return; kunmap_high(page); @@ -89,8 +88,7 @@ static inline void *kmap_atomic(struct page *page, enum km_type type) idx = type + KM_TYPE_NR*smp_processor_id(); vaddr = KMAP_FIX_BEGIN + idx * PAGE_SIZE; #if HIGHMEM_DEBUG - if (!pte_none(*(kmap_pte+idx))) - BUG(); + BUG_ON(!pte_none(*(kmap_pte+idx))); #endif set_pte(kmap_pte+idx, mk_pte(page, kmap_prot)); flush_tlb_page(0, vaddr); @@ -110,8 +108,7 @@ static inline void kunmap_atomic(void *kvaddr, enum km_type type) return; } - if (vaddr != KMAP_FIX_BEGIN + idx * PAGE_SIZE) - BUG(); + BUG_ON(vaddr != KMAP_FIX_BEGIN + idx * PAGE_SIZE); /* * force other mappings to Oops if they'll try to access diff --git a/include/asm-ppc/pci.h b/include/asm-ppc/pci.h index 763765257bfc..5dad69a5ee61 100644 --- a/include/asm-ppc/pci.h +++ b/include/asm-ppc/pci.h @@ -105,8 +105,7 @@ static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, static inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction) { - if (direction == PCI_DMA_NONE) - BUG(); + BUG_ON(direction == PCI_DMA_NONE); /* nothing to do */ } @@ -134,8 +133,7 @@ static inline dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page, static inline void pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address, size_t size, int direction) { - if (direction == PCI_DMA_NONE) - BUG(); + BUG_ON(direction == PCI_DMA_NONE); /* Nothing to do */ } @@ -159,8 +157,7 @@ static inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, { int i; - if (direction == PCI_DMA_NONE) - BUG(); + BUG_ON(direction == PCI_DMA_NONE); /* * temporary 2.4 hack diff --git a/include/asm-ppc64/pci.h b/include/asm-ppc64/pci.h index 5c3515a500a9..305ca8cd8235 100644 --- a/include/asm-ppc64/pci.h +++ b/include/asm-ppc64/pci.h @@ -65,8 +65,7 @@ static inline void pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction) { - if (direction == PCI_DMA_NONE) - BUG(); + BUG_ON(direction == PCI_DMA_NONE); /* nothing to do */ } @@ -74,8 +73,7 @@ static inline void pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction) { - if (direction == PCI_DMA_NONE) - BUG(); + BUG_ON(direction == PCI_DMA_NONE); /* nothing to do */ } diff --git a/include/asm-ppc64/topology.h b/include/asm-ppc64/topology.h index 9be503f666f9..a41ca6cba882 100644 --- a/include/asm-ppc64/topology.h +++ b/include/asm-ppc64/topology.h @@ -13,8 +13,7 @@ static inline int cpu_to_node(int cpu) node = numa_cpu_lookup_table[cpu]; #ifdef DEBUG_NUMA - if (node == -1) - BUG(); + BUG_ON(node == -1); #endif return node; diff --git a/include/asm-s390/idals.h b/include/asm-s390/idals.h index 64c783f9b7f2..890bc145f9dd 100644 --- a/include/asm-s390/idals.h +++ b/include/asm-s390/idals.h @@ -223,8 +223,7 @@ idal_buffer_to_user(struct idal_buffer *ib, void *to, size_t count) size_t left; int i; - if (count > ib->size) - BUG(); + BUG_ON(count > ib->size); for (i = 0; count > IDA_BLOCK_SIZE; i++) { left = copy_to_user(to, ib->data[i], IDA_BLOCK_SIZE); if (left) @@ -244,8 +243,7 @@ idal_buffer_from_user(struct idal_buffer *ib, const void *from, size_t count) size_t left; int i; - if (count > ib->size) - BUG(); + BUG_ON(count > ib->size); for (i = 0; count > IDA_BLOCK_SIZE; i++) { left = copy_from_user(ib->data[i], from, IDA_BLOCK_SIZE); if (left) diff --git a/include/asm-sh/spinlock.h b/include/asm-sh/spinlock.h index c0adea380ac7..9930f93b1f14 100644 --- a/include/asm-sh/spinlock.h +++ b/include/asm-sh/spinlock.h @@ -48,8 +48,7 @@ static inline void _raw_spin_lock(spinlock_t *lock) static inline void _raw_spin_unlock(spinlock_t *lock) { #ifdef CONFIG_DEBUG_SPINLOCK - if (!spin_is_locked(lock)) - BUG(); + BUG_ON(!spin_is_locked(lock)); #endif lock->lock = 0; diff --git a/include/asm-sparc64/floppy.h b/include/asm-sparc64/floppy.h index 8beed5df56b3..1bc43aaa49eb 100644 --- a/include/asm-sparc64/floppy.h +++ b/include/asm-sparc64/floppy.h @@ -320,10 +320,9 @@ static void sun_pci_fd_lde_broken_outb(unsigned char val, unsigned long port) static void sun_pci_fd_enable_dma(void) { - if ((NULL == sun_pci_dma_pending.buf) || + BUG_ON((NULL == sun_pci_dma_pending.buf) || (0 == sun_pci_dma_pending.len) || - (0 == sun_pci_dma_pending.direction)) - BUG(); + (0 == sun_pci_dma_pending.direction)); sun_pci_dma_current.buf = sun_pci_dma_pending.buf; sun_pci_dma_current.len = sun_pci_dma_pending.len; diff --git a/include/asm-sparc64/tlbflush.h b/include/asm-sparc64/tlbflush.h index 982829f3dc16..8c70fdd037b6 100644 --- a/include/asm-sparc64/tlbflush.h +++ b/include/asm-sparc64/tlbflush.h @@ -90,10 +90,9 @@ static __inline__ void flush_tlb_pgtables(struct mm_struct *mm, unsigned long st { /* Note the signed type. */ long s = start, e = end, vpte_base; - if (s > e) /* Nobody should call us with start below VM hole and end above. See if it is really true. */ - BUG(); + BUG_ON(s > e); #if 0 /* Currently free_pgtables guarantees this. */ s &= PMD_MASK; diff --git a/include/asm-x86_64/pgalloc.h b/include/asm-x86_64/pgalloc.h index e15895c99a4e..bebcaab3375c 100644 --- a/include/asm-x86_64/pgalloc.h +++ b/include/asm-x86_64/pgalloc.h @@ -24,8 +24,7 @@ extern __inline__ pmd_t *get_pmd(void) extern __inline__ void pmd_free(pmd_t *pmd) { - if ((unsigned long)pmd & (PAGE_SIZE-1)) - BUG(); + BUG_ON((unsigned long)pmd & (PAGE_SIZE-1)); free_page((unsigned long)pmd); } @@ -41,8 +40,7 @@ static inline pgd_t *pgd_alloc (struct mm_struct *mm) static inline void pgd_free (pgd_t *pgd) { - if ((unsigned long)pgd & (PAGE_SIZE-1)) - BUG(); + BUG_ON((unsigned long)pgd & (PAGE_SIZE-1)); free_page((unsigned long)pgd); } @@ -64,8 +62,7 @@ static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long add extern __inline__ void pte_free_kernel(pte_t *pte) { - if ((unsigned long)pte & (PAGE_SIZE-1)) - BUG(); + BUG_ON((unsigned long)pte & (PAGE_SIZE-1)); free_page((unsigned long)pte); } diff --git a/include/asm-x86_64/spinlock.h b/include/asm-x86_64/spinlock.h index ae3615feecdb..c341097c7106 100644 --- a/include/asm-x86_64/spinlock.h +++ b/include/asm-x86_64/spinlock.h @@ -70,10 +70,8 @@ typedef struct { static inline void _raw_spin_unlock(spinlock_t *lock) { #ifdef CONFIG_DEBUG_SPINLOCK - if (lock->magic != SPINLOCK_MAGIC) - BUG(); - if (!spin_is_locked(lock)) - BUG(); + BUG_ON(lock->magic != SPINLOCK_MAGIC); + BUG_ON(!spin_is_locked(lock)); #endif __asm__ __volatile__( spin_unlock_string @@ -91,10 +89,8 @@ static inline void _raw_spin_unlock(spinlock_t *lock) { char oldval = 1; #ifdef CONFIG_DEBUG_SPINLOCK - if (lock->magic != SPINLOCK_MAGIC) - BUG(); - if (!spin_is_locked(lock)) - BUG(); + BUG_ON(lock->magic != SPINLOCK_MAGIC); + BUG_ON(!spin_is_locked(lock)); #endif __asm__ __volatile__( spin_unlock_string @@ -174,8 +170,7 @@ typedef struct { static inline void _raw_read_lock(rwlock_t *rw) { #ifdef CONFIG_DEBUG_SPINLOCK - if (rw->magic != RWLOCK_MAGIC) - BUG(); + BUG_ON(rw->magic != RWLOCK_MAGIC); #endif __build_read_lock(rw, "__read_lock_failed"); } @@ -183,8 +178,7 @@ static inline void _raw_read_lock(rwlock_t *rw) static inline void _raw_write_lock(rwlock_t *rw) { #ifdef CONFIG_DEBUG_SPINLOCK - if (rw->magic != RWLOCK_MAGIC) - BUG(); + BUG_ON(rw->magic != RWLOCK_MAGIC); #endif __build_write_lock(rw, "__write_lock_failed"); } diff --git a/include/linux/bio.h b/include/linux/bio.h index 4f090059372e..d3b4e9ed4052 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -266,8 +266,7 @@ extern inline char *bvec_kmap_irq(struct bio_vec *bvec, unsigned long *flags) local_irq_save(*flags); addr = (unsigned long) kmap_atomic(bvec->bv_page, KM_BIO_SRC_IRQ); - if (addr & ~PAGE_MASK) - BUG(); + BUG_ON(addr & ~PAGE_MASK); return (char *) addr + bvec->bv_offset; } diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index 5f4b675a7bb4..110584f07883 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h @@ -125,8 +125,7 @@ BUFFER_FNS(Write_EIO,write_io_error) /* If we *know* page->private refers to buffer_heads */ #define page_buffers(page) \ ({ \ - if (!PagePrivate(page)) \ - BUG(); \ + BUG_ON(!PagePrivate(page)); \ ((struct buffer_head *)(page)->private); \ }) #define page_has_buffers(page) PagePrivate(page) diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 6bd0570d3a1c..6b2ea8fecf06 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -270,8 +270,7 @@ extern char * d_path(struct dentry *, struct vfsmount *, char *, int); static inline struct dentry *dget(struct dentry *dentry) { if (dentry) { - if (!atomic_read(&dentry->d_count)) - BUG(); + BUG_ON(!atomic_read(&dentry->d_count)); atomic_inc(&dentry->d_count); } return dentry; diff --git a/include/linux/highmem.h b/include/linux/highmem.h index 2c9139a94f8f..232d8fdb557c 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h @@ -56,8 +56,7 @@ static inline void memclear_highpage_flush(struct page *page, unsigned int offse { void *kaddr; - if (offset + size > PAGE_SIZE) - BUG(); + BUG_ON(offset + size > PAGE_SIZE); kaddr = kmap_atomic(page, KM_USER0); memset((char *)kaddr + offset, 0, size); diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 666d89f875f5..cfdeaaad2b7e 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -831,7 +831,7 @@ static inline void netif_rx_complete(struct net_device *dev) unsigned long flags; local_irq_save(flags); - if (!test_bit(__LINK_STATE_RX_SCHED, &dev->state)) BUG(); + BUG_ON(!test_bit(__LINK_STATE_RX_SCHED, &dev->state)); list_del(&dev->poll_list); smp_mb__before_clear_bit(); clear_bit(__LINK_STATE_RX_SCHED, &dev->state); @@ -857,7 +857,7 @@ static inline void netif_poll_enable(struct net_device *dev) */ static inline void __netif_rx_complete(struct net_device *dev) { - if (!test_bit(__LINK_STATE_RX_SCHED, &dev->state)) BUG(); + BUG_ON(!test_bit(__LINK_STATE_RX_SCHED, &dev->state)); list_del(&dev->poll_list); smp_mb__before_clear_bit(); clear_bit(__LINK_STATE_RX_SCHED, &dev->state); diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 93edc5a5ad98..5ae592b26d63 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -255,8 +255,7 @@ nfs_file_cred(struct file *file) if (file) cred = (struct rpc_cred *)file->private_data; #ifdef RPC_DEBUG - if (cred && cred->cr_magic != RPCAUTH_CRED_MAGIC) - BUG(); + BUG_ON(cred && cred->cr_magic != RPCAUTH_CRED_MAGIC); #endif return cred; } diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index ad88acfd7b70..155c9a2af016 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -44,8 +44,7 @@ extern struct quotactl_ops vfs_quotactl_ops; static __inline__ void DQUOT_INIT(struct inode *inode) { - if (!inode->i_sb) - BUG(); + BUG_ON(!inode->i_sb); if (sb_any_quota_enabled(inode->i_sb) && !IS_NOQUOTA(inode)) inode->i_sb->dq_op->initialize(inode, -1); } @@ -53,8 +52,7 @@ static __inline__ void DQUOT_INIT(struct inode *inode) static __inline__ void DQUOT_DROP(struct inode *inode) { if (IS_QUOTAINIT(inode)) { - if (!inode->i_sb) - BUG(); + BUG_ON(!inode->i_sb); inode->i_sb->dq_op->drop(inode); /* Ops must be set when there's any quota... */ } } diff --git a/include/linux/smp_lock.h b/include/linux/smp_lock.h index 80fbd56eb3e4..9a20995c531a 100644 --- a/include/linux/smp_lock.h +++ b/include/linux/smp_lock.h @@ -49,8 +49,7 @@ static inline void lock_kernel(void) static inline void unlock_kernel(void) { - if (unlikely(current->lock_depth < 0)) - BUG(); + BUG_ON(current->lock_depth < 0); if (likely(--current->lock_depth < 0)) put_kernel_lock(); } diff --git a/include/net/sock.h b/include/net/sock.h index 16e129f90426..115ace226a2a 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -473,8 +473,8 @@ static __inline__ void sk_set_owner(struct sock *sk, struct module *owner) * change the ownership of this struct sock, with one not needed * transient sk_set_owner call. */ - if (unlikely(sk->sk_owner != NULL)) - BUG(); + BUG_ON(sk->sk_owner != NULL); + sk->sk_owner = owner; __module_get(owner); } diff --git a/include/net/tcp.h b/include/net/tcp.h index aeea9b268f80..4ef3b80fe541 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1457,7 +1457,7 @@ static __inline__ int tcp_prequeue(struct sock *sk, struct sk_buff *skb) if (tp->ucopy.memory > sk->sk_rcvbuf) { struct sk_buff *skb1; - if (sock_owned_by_user(sk)) BUG(); + BUG_ON(sock_owned_by_user(sk)); while ((skb1 = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) { sk->sk_backlog_rcv(sk, skb1); diff --git a/include/rxrpc/call.h b/include/rxrpc/call.h index 6ac1df7012e9..9f0ce416a13e 100644 --- a/include/rxrpc/call.h +++ b/include/rxrpc/call.h @@ -187,8 +187,7 @@ extern int rxrpc_incoming_call(struct rxrpc_connection *conn, static inline void rxrpc_get_call(struct rxrpc_call *call) { - if (atomic_read(&call->usage)<=0) - BUG(); + BUG_ON(atomic_read(&call->usage)<=0); atomic_inc(&call->usage); /*printk("rxrpc_get_call(%p{u=%d})\n",(C),atomic_read(&(C)->usage));*/ } diff --git a/include/rxrpc/connection.h b/include/rxrpc/connection.h index 14de354724f9..f22e71097952 100644 --- a/include/rxrpc/connection.h +++ b/include/rxrpc/connection.h @@ -67,8 +67,7 @@ extern int rxrpc_connection_lookup(struct rxrpc_peer *peer, static inline void rxrpc_get_connection(struct rxrpc_connection *conn) { - if (atomic_read(&conn->usage)<0) - BUG(); + BUG_ON(atomic_read(&conn->usage)<0); atomic_inc(&conn->usage); //printk("rxrpc_get_conn(%p{u=%d})\n",conn,atomic_read(&conn->usage)); } diff --git a/include/rxrpc/message.h b/include/rxrpc/message.h index 9be208ab079e..d5755c6db3a8 100644 --- a/include/rxrpc/message.h +++ b/include/rxrpc/message.h @@ -53,8 +53,7 @@ struct rxrpc_message extern void __rxrpc_put_message(struct rxrpc_message *msg); static inline void rxrpc_put_message(struct rxrpc_message *msg) { - if (atomic_read(&msg->usage)<=0) - BUG(); + BUG_ON(atomic_read(&msg->usage)<=0); if (atomic_dec_and_test(&msg->usage)) __rxrpc_put_message(msg); } diff --git a/include/rxrpc/peer.h b/include/rxrpc/peer.h index 07e3a51b60b6..da4832fccd6a 100644 --- a/include/rxrpc/peer.h +++ b/include/rxrpc/peer.h @@ -72,8 +72,7 @@ extern int rxrpc_peer_lookup(struct rxrpc_transport *trans, static inline void rxrpc_get_peer(struct rxrpc_peer *peer) { - if (atomic_read(&peer->usage)<0) - BUG(); + BUG_ON(atomic_read(&peer->usage)<0); atomic_inc(&peer->usage); //printk("rxrpc_get_peer(%p{u=%d})\n",peer,atomic_read(&peer->usage)); } diff --git a/include/rxrpc/transport.h b/include/rxrpc/transport.h index 92fb49c7d4b9..6aa88691186c 100644 --- a/include/rxrpc/transport.h +++ b/include/rxrpc/transport.h @@ -85,8 +85,7 @@ extern int rxrpc_create_transport(unsigned short port, static inline void rxrpc_get_transport(struct rxrpc_transport *trans) { - if (atomic_read(&trans->usage) <= 0) - BUG(); + BUG_ON(atomic_read(&trans->usage) <= 0); atomic_inc(&trans->usage); //printk("rxrpc_get_transport(%p{u=%d})\n", // trans, atomic_read(&trans->usage)); -- cgit v1.2.3 From 6c5703d5677a3f5b8f74aa08c1e46d200a6e21b5 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 19 Jan 2004 05:14:46 -0800 Subject: [PATCH] rq_for_each_bio fix From: Xavier Bestel Within the body of this macro we are accessing rq->bio, but `bio' is an arg to the macro. If someone uses this macro with some variable which is not named `bio' it won't compile. So use a more-likely-to-be-unique identifier for the macro. --- include/linux/blkdev.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index a1c5cd076331..80b4c47842b8 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -483,9 +483,9 @@ static inline void blk_queue_bounce(request_queue_t *q, struct bio **bio) } #endif /* CONFIG_MMU */ -#define rq_for_each_bio(bio, rq) \ +#define rq_for_each_bio(_bio, rq) \ if ((rq->bio)) \ - for (bio = (rq)->bio; bio; bio = bio->bi_next) + for (_bio = (rq)->bio; _bio; _bio = bio->bi_next) struct sec_size { unsigned block_size; -- cgit v1.2.3 From 8ce5870de372c3f15c4d34539e08305f70516139 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 19 Jan 2004 05:15:48 -0800 Subject: [PATCH] Remove CLONE_DETACHED From: Andries.Brouwer@cwi.nl Remove obsolete CLONE_DETACHED --- include/linux/sched.h | 2 +- kernel/fork.c | 16 ---------------- 2 files changed, 1 insertion(+), 17 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index dba09fa98441..f5f84aedbaec 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -50,7 +50,7 @@ struct exec_domain; #define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */ #define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */ #define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */ -#define CLONE_DETACHED 0x00400000 /* Not used - CLONE_THREAD implies detached uniquely */ +#define CLONE_DETACHED 0x00400000 /* Unused, ignored */ #define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */ #define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */ #define CLONE_STOPPED 0x02000000 /* Start in stopped state */ diff --git a/kernel/fork.c b/kernel/fork.c index ea2eeb1ed644..b703d95dadc7 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -859,22 +859,6 @@ struct task_struct *copy_process(unsigned long clone_flags, if ((clone_flags & CLONE_SIGHAND) && !(clone_flags & CLONE_VM)) return ERR_PTR(-EINVAL); - /* - * CLONE_DETACHED must match CLONE_THREAD: it's a historical - * thing. - */ - if (!(clone_flags & CLONE_DETACHED) != !(clone_flags & CLONE_THREAD)) { - /* Warn about the old no longer supported case so that we see it */ - if (clone_flags & CLONE_THREAD) { - static int count; - if (count < 5) { - count++; - printk(KERN_WARNING "%s trying to use CLONE_THREAD without CLONE_DETACH\n", current->comm); - } - } - return ERR_PTR(-EINVAL); - } - retval = security_task_create(clone_flags); if (retval) goto fork_out; -- cgit v1.2.3 From 7685e7edb44ed047fffe9954b12a76896ec15194 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 19 Jan 2004 05:15:58 -0800 Subject: [PATCH] uninline bitmap functions - A couple of them are using alloca (via DECLARE_BITMAP) and this generates a cannot-inline warning with -Winline. - These functions are too big to inline anwyay. --- include/linux/bitmap.h | 140 +++++-------------------------------------------- lib/Makefile | 3 +- lib/bitmap.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 156 insertions(+), 127 deletions(-) create mode 100644 lib/bitmap.c (limited to 'include/linux') diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h index 74b89ea0aae5..b84caaebed87 100644 --- a/include/linux/bitmap.h +++ b/include/linux/bitmap.h @@ -10,57 +10,11 @@ #include #include -static inline int bitmap_empty(const unsigned long *bitmap, int bits) -{ - int k, lim = bits/BITS_PER_LONG; - for (k = 0; k < lim; ++k) - if (bitmap[k]) - return 0; - - if (bits % BITS_PER_LONG) - if (bitmap[k] & ((1UL << (bits % BITS_PER_LONG)) - 1)) - return 0; - - return 1; -} - -static inline int bitmap_full(const unsigned long *bitmap, int bits) -{ - int k, lim = bits/BITS_PER_LONG; - for (k = 0; k < lim; ++k) - if (~bitmap[k]) - return 0; - - if (bits % BITS_PER_LONG) - if (~bitmap[k] & ((1UL << (bits % BITS_PER_LONG)) - 1)) - return 0; - - return 1; -} - -static inline int bitmap_equal(const unsigned long *bitmap1, - unsigned long *bitmap2, int bits) -{ - int k, lim = bits/BITS_PER_LONG;; - for (k = 0; k < lim; ++k) - if (bitmap1[k] != bitmap2[k]) - return 0; - - if (bits % BITS_PER_LONG) - if ((bitmap1[k] ^ bitmap2[k]) & - ((1UL << (bits % BITS_PER_LONG)) - 1)) - return 0; - - return 1; -} - -static inline void bitmap_complement(unsigned long *bitmap, int bits) -{ - int k; - - for (k = 0; k < BITS_TO_LONGS(bits); ++k) - bitmap[k] = ~bitmap[k]; -} +int bitmap_empty(const unsigned long *bitmap, int bits); +int bitmap_full(const unsigned long *bitmap, int bits); +int bitmap_equal(const unsigned long *bitmap1, + unsigned long *bitmap2, int bits); +void bitmap_complement(unsigned long *bitmap, int bits); static inline void bitmap_clear(unsigned long *bitmap, int bits) { @@ -78,81 +32,15 @@ static inline void bitmap_copy(unsigned long *dst, memcpy(dst, src, BITS_TO_LONGS(bits)*sizeof(unsigned long)); } -static inline void bitmap_shift_right(unsigned long *dst, - const unsigned long *src, int shift, int bits) -{ - int k; - DECLARE_BITMAP(__shr_tmp, bits); - - bitmap_clear(__shr_tmp, bits); - for (k = 0; k < bits - shift; ++k) - if (test_bit(k + shift, src)) - set_bit(k, __shr_tmp); - bitmap_copy(dst, __shr_tmp, bits); -} - -static inline void bitmap_shift_left(unsigned long *dst, - const unsigned long *src, int shift, int bits) -{ - int k; - DECLARE_BITMAP(__shl_tmp, bits); - - bitmap_clear(__shl_tmp, bits); - for (k = bits; k >= shift; --k) - if (test_bit(k - shift, src)) - set_bit(k, __shl_tmp); - bitmap_copy(dst, __shl_tmp, bits); -} - -static inline void bitmap_and(unsigned long *dst, const unsigned long *bitmap1, - const unsigned long *bitmap2, int bits) -{ - int k; - int nr = BITS_TO_LONGS(bits); - - for (k = 0; k < nr; k++) - dst[k] = bitmap1[k] & bitmap2[k]; -} - -static inline void bitmap_or(unsigned long *dst, const unsigned long *bitmap1, - const unsigned long *bitmap2, int bits) -{ - int k; - int nr = BITS_TO_LONGS(bits); - - for (k = 0; k < nr; k++) - dst[k] = bitmap1[k] | bitmap2[k]; -} - -#if BITS_PER_LONG == 32 -static inline int bitmap_weight(const unsigned long *bitmap, int bits) -{ - int k, w = 0, lim = bits/BITS_PER_LONG; - - for (k = 0; k < lim; k++) - w += hweight32(bitmap[k]); - - if (bits % BITS_PER_LONG) - w += hweight32(bitmap[k] & - ((1UL << (bits % BITS_PER_LONG)) - 1)); - - return w; -} -#else -static inline int bitmap_weight(const unsigned long *bitmap, int bits) -{ - int k, w = 0, lim = bits/BITS_PER_LONG; - - for (k = 0; k < lim; k++) - w += hweight64(bitmap[k]); - - if (bits % BITS_PER_LONG) - w += hweight64(bitmap[k] & - ((1UL << (bits % BITS_PER_LONG)) - 1)); - - return w; -} -#endif +void bitmap_shift_right(unsigned long *dst, + const unsigned long *src, int shift, int bits); +void bitmap_shift_left(unsigned long *dst, + const unsigned long *src, int shift, int bits); +void bitmap_and(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits); +void bitmap_or(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits); +int bitmap_weight(const unsigned long *bitmap, int bits); #endif /* __ASSEMBLY__ */ diff --git a/lib/Makefile b/lib/Makefile index c588784b3bef..15f8ca078332 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -5,7 +5,8 @@ lib-y := errno.o ctype.o string.o vsprintf.o cmdline.o \ bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \ - kobject.o idr.o div64.o parser.o int_sqrt.o mask.o + kobject.o idr.o div64.o parser.o int_sqrt.o mask.o \ + bitmap.o lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o diff --git a/lib/bitmap.c b/lib/bitmap.c new file mode 100644 index 000000000000..fd2b38f8db49 --- /dev/null +++ b/lib/bitmap.c @@ -0,0 +1,140 @@ +#include +#include + +int bitmap_empty(const unsigned long *bitmap, int bits) +{ + int k, lim = bits/BITS_PER_LONG; + for (k = 0; k < lim; ++k) + if (bitmap[k]) + return 0; + + if (bits % BITS_PER_LONG) + if (bitmap[k] & ((1UL << (bits % BITS_PER_LONG)) - 1)) + return 0; + + return 1; +} +EXPORT_SYMBOL(bitmap_empty); + +int bitmap_full(const unsigned long *bitmap, int bits) +{ + int k, lim = bits/BITS_PER_LONG; + for (k = 0; k < lim; ++k) + if (~bitmap[k]) + return 0; + + if (bits % BITS_PER_LONG) + if (~bitmap[k] & ((1UL << (bits % BITS_PER_LONG)) - 1)) + return 0; + + return 1; +} +EXPORT_SYMBOL(bitmap_full); + +int bitmap_equal(const unsigned long *bitmap1, + unsigned long *bitmap2, int bits) +{ + int k, lim = bits/BITS_PER_LONG;; + for (k = 0; k < lim; ++k) + if (bitmap1[k] != bitmap2[k]) + return 0; + + if (bits % BITS_PER_LONG) + if ((bitmap1[k] ^ bitmap2[k]) & + ((1UL << (bits % BITS_PER_LONG)) - 1)) + return 0; + + return 1; +} +EXPORT_SYMBOL(bitmap_equal); + +void bitmap_complement(unsigned long *bitmap, int bits) +{ + int k; + + for (k = 0; k < BITS_TO_LONGS(bits); ++k) + bitmap[k] = ~bitmap[k]; +} +EXPORT_SYMBOL(bitmap_complement); + +void bitmap_shift_right(unsigned long *dst, + const unsigned long *src, int shift, int bits) +{ + int k; + DECLARE_BITMAP(__shr_tmp, bits); + + bitmap_clear(__shr_tmp, bits); + for (k = 0; k < bits - shift; ++k) + if (test_bit(k + shift, src)) + set_bit(k, __shr_tmp); + bitmap_copy(dst, __shr_tmp, bits); +} +EXPORT_SYMBOL(bitmap_shift_right); + +void bitmap_shift_left(unsigned long *dst, + const unsigned long *src, int shift, int bits) +{ + int k; + DECLARE_BITMAP(__shl_tmp, bits); + + bitmap_clear(__shl_tmp, bits); + for (k = bits; k >= shift; --k) + if (test_bit(k - shift, src)) + set_bit(k, __shl_tmp); + bitmap_copy(dst, __shl_tmp, bits); +} +EXPORT_SYMBOL(bitmap_shift_left); + +void bitmap_and(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits) +{ + int k; + int nr = BITS_TO_LONGS(bits); + + for (k = 0; k < nr; k++) + dst[k] = bitmap1[k] & bitmap2[k]; +} +EXPORT_SYMBOL(bitmap_and); + +void bitmap_or(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits) +{ + int k; + int nr = BITS_TO_LONGS(bits); + + for (k = 0; k < nr; k++) + dst[k] = bitmap1[k] | bitmap2[k]; +} +EXPORT_SYMBOL(bitmap_or); + +#if BITS_PER_LONG == 32 +int bitmap_weight(const unsigned long *bitmap, int bits) +{ + int k, w = 0, lim = bits/BITS_PER_LONG; + + for (k = 0; k < lim; k++) + w += hweight32(bitmap[k]); + + if (bits % BITS_PER_LONG) + w += hweight32(bitmap[k] & + ((1UL << (bits % BITS_PER_LONG)) - 1)); + + return w; +} +#else +int bitmap_weight(const unsigned long *bitmap, int bits) +{ + int k, w = 0, lim = bits/BITS_PER_LONG; + + for (k = 0; k < lim; k++) + w += hweight64(bitmap[k]); + + if (bits % BITS_PER_LONG) + w += hweight64(bitmap[k] & + ((1UL << (bits % BITS_PER_LONG)) - 1)); + + return w; +} +#endif +EXPORT_SYMBOL(bitmap_weight); + -- cgit v1.2.3