From 816b9bb2f7462ba0716a7db4c42fb39933d929ab Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 12 May 2003 07:18:16 -0700 Subject: [IPV4/IPV6]: Consolidate saddr resetting into inet_reset_saddr(). --- include/net/ip.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'include') diff --git a/include/net/ip.h b/include/net/ip.h index 25e95ec9b4fb..b17e641f537d 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -230,6 +230,23 @@ static inline void ip_eth_mc_map(u32 addr, char *buf) buf[3]=addr&0x7F; } +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +#include +#endif + +static __inline__ void inet_reset_saddr(struct sock *sk) +{ + inet_sk(sk)->rcv_saddr = inet_sk(sk)->saddr = 0; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + if (sk->family == PF_INET6) { + struct ipv6_pinfo *np = inet6_sk(sk); + + memset(&np->saddr, 0, sizeof(np->saddr)); + memset(&np->rcv_saddr, 0, sizeof(np->rcv_saddr)); + } +#endif +} + #endif extern int ip_call_ra_chain(struct sk_buff *skb); -- cgit v1.2.3 From 9b87a519169800ab6b9becbaf51051ffb006ddb9 Mon Sep 17 00:00:00 2001 From: Steven Cole Date: Mon, 12 May 2003 07:31:01 -0700 Subject: [PATCH] more potentially undefined preprocessor symbols Here are three more fixes which I missed in the previous patch. --- arch/parisc/hpux/wrappers.S | 2 +- include/linux/smp_lock.h | 2 +- include/linux/tpqic02.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/arch/parisc/hpux/wrappers.S b/arch/parisc/hpux/wrappers.S index c9322351a85c..6f26159bed61 100644 --- a/arch/parisc/hpux/wrappers.S +++ b/arch/parisc/hpux/wrappers.S @@ -129,7 +129,7 @@ fork_exit: /* Set the return value for the child */ hpux_child_return: -#if CONFIG_SMP || CONFIG_PREEMPT +#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT) bl schedule_tail, %r2 nop #endif diff --git a/include/linux/smp_lock.h b/include/linux/smp_lock.h index 5a0b83a677d9..80fbd56eb3e4 100644 --- a/include/linux/smp_lock.h +++ b/include/linux/smp_lock.h @@ -5,7 +5,7 @@ #include #include -#if CONFIG_SMP || CONFIG_PREEMPT +#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT) extern spinlock_t kernel_flag; diff --git a/include/linux/tpqic02.h b/include/linux/tpqic02.h index 2972cb2f827c..f980d4ff01fe 100644 --- a/include/linux/tpqic02.h +++ b/include/linux/tpqic02.h @@ -12,7 +12,7 @@ #include -#if CONFIG_QIC02_TAPE || CONFIG_QIC02_TAPE_MODULE +#if defined(CONFIG_QIC02_TAPE) || defined(CONFIG_QIC02_TAPE_MODULE) /* need to have QIC02_TAPE_DRIVE and QIC02_TAPE_IFC expand to something */ #include -- cgit v1.2.3 From a7780700a81962993c7aefe71807b54a25be4a2b Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 12 May 2003 09:09:47 -0700 Subject: [PATCH] Remove __verify_write leftovers From: Taral Looks like the recent access_ok fixes broke building of i386. __verify_write is still referenced in a couple places. --- arch/i386/kernel/i386_ksyms.c | 3 --- include/asm-i386/uaccess.h | 2 -- 2 files changed, 5 deletions(-) (limited to 'include') diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c index c300e0569741..ad9e9446002d 100644 --- a/arch/i386/kernel/i386_ksyms.c +++ b/arch/i386/kernel/i386_ksyms.c @@ -73,9 +73,6 @@ EXPORT_SYMBOL(physnode_map); #ifdef CONFIG_X86_NUMAQ EXPORT_SYMBOL(xquad_portio); #endif -#ifndef CONFIG_X86_WP_WORKS_OK -EXPORT_SYMBOL(__verify_write); -#endif EXPORT_SYMBOL(dump_thread); EXPORT_SYMBOL(dump_fpu); EXPORT_SYMBOL(dump_extended_fpu); diff --git a/include/asm-i386/uaccess.h b/include/asm-i386/uaccess.h index 15aa2e7ef765..07caa21a978c 100644 --- a/include/asm-i386/uaccess.h +++ b/include/asm-i386/uaccess.h @@ -42,8 +42,6 @@ extern struct movsl_mask { } ____cacheline_aligned_in_smp movsl_mask; #endif -int __verify_write(const void *, unsigned long); - #define __addr_ok(addr) ((unsigned long)(addr) < (current_thread_info()->addr_limit.seg)) /* -- cgit v1.2.3 From b7df5197b4b05adfa66563a5908d29ef74c0fc64 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 12 May 2003 09:10:05 -0700 Subject: [PATCH] implement module_arch_cleanup() in all architectures From: Rusty Russell , David Mosberger The patch below updates the other platforms with module_arch_cleanup(). Also, I added more debug output to kernel/module.c since I found it useful to be able to see the final section layout. --- arch/alpha/kernel/module.c | 5 +++++ arch/arm/kernel/module.c | 5 +++++ arch/i386/kernel/module.c | 4 ++++ arch/parisc/kernel/module.c | 4 ++++ arch/ppc/kernel/module.c | 4 ++++ arch/ppc64/kernel/module.c | 4 ++++ arch/s390/kernel/module.c | 4 ++++ arch/sparc/kernel/module.c | 4 ++++ arch/sparc64/kernel/module.c | 4 ++++ arch/v850/kernel/module.c | 5 +++++ arch/x86_64/kernel/module.c | 4 ++++ include/linux/moduleloader.h | 3 +++ kernel/module.c | 5 +++++ 13 files changed, 55 insertions(+) (limited to 'include') diff --git a/arch/alpha/kernel/module.c b/arch/alpha/kernel/module.c index f444a94eb965..425928769c1d 100644 --- a/arch/alpha/kernel/module.c +++ b/arch/alpha/kernel/module.c @@ -300,3 +300,8 @@ module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, { return 0; } + +void +module_arch_cleanup(struct module *mod) +{ +} diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index c79822e3bb88..6d1f4a8d1426 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c @@ -159,3 +159,8 @@ module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, { return 0; } + +void +module_arch_cleanup(struct module *mod) +{ +} diff --git a/arch/i386/kernel/module.c b/arch/i386/kernel/module.c index 463a2c7e0acc..e8258ad35860 100644 --- a/arch/i386/kernel/module.c +++ b/arch/i386/kernel/module.c @@ -123,3 +123,7 @@ int module_finalize(const Elf_Ehdr *hdr, } return 0; } + +void module_arch_cleanup(struct module *mod) +{ +} diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index 703991db6276..936eba6c6b99 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c @@ -568,3 +568,7 @@ int module_finalize(const Elf_Ehdr *hdr, #endif return 0; } + +void module_arch_cleanup(struct module *mod) +{ +} diff --git a/arch/ppc/kernel/module.c b/arch/ppc/kernel/module.c index e9e586cb0718..d263eacc0625 100644 --- a/arch/ppc/kernel/module.c +++ b/arch/ppc/kernel/module.c @@ -269,3 +269,7 @@ int module_finalize(const Elf_Ehdr *hdr, { return 0; } + +void module_arch_cleanup(struct module *mod) +{ +} diff --git a/arch/ppc64/kernel/module.c b/arch/ppc64/kernel/module.c index 7b27cdd29fa0..8847feb93b1a 100644 --- a/arch/ppc64/kernel/module.c +++ b/arch/ppc64/kernel/module.c @@ -384,3 +384,7 @@ int module_finalize(const Elf_Ehdr *hdr, me->num_exentries); return 0; } + +void module_arch_cleanup(struct module *mod) +{ +} diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c index d79e7345264e..913a21691c2f 100644 --- a/arch/s390/kernel/module.c +++ b/arch/s390/kernel/module.c @@ -386,3 +386,7 @@ int module_finalize(const Elf_Ehdr *hdr, kfree(me->arch.syminfo); return 0; } + +void module_arch_cleanup(struct module *mod) +{ +} diff --git a/arch/sparc/kernel/module.c b/arch/sparc/kernel/module.c index 99183d7f24bf..1bde20c52683 100644 --- a/arch/sparc/kernel/module.c +++ b/arch/sparc/kernel/module.c @@ -145,3 +145,7 @@ int module_finalize(const Elf_Ehdr *hdr, { return 0; } + +void module_arch_cleanup(struct module *mod) +{ +} diff --git a/arch/sparc64/kernel/module.c b/arch/sparc64/kernel/module.c index 9918b76c6280..c24ee5aeaa27 100644 --- a/arch/sparc64/kernel/module.c +++ b/arch/sparc64/kernel/module.c @@ -273,3 +273,7 @@ int module_finalize(const Elf_Ehdr *hdr, { return 0; } + +void module_arch_cleanup(struct module *mod) +{ +} diff --git a/arch/v850/kernel/module.c b/arch/v850/kernel/module.c index eedced8ddb19..64aeb3e37c52 100644 --- a/arch/v850/kernel/module.c +++ b/arch/v850/kernel/module.c @@ -230,3 +230,8 @@ int apply_relocate_add (Elf32_Shdr *sechdrs, const char *strtab, return 0; } + +void +module_arch_cleanup(struct module *mod) +{ +} diff --git a/arch/x86_64/kernel/module.c b/arch/x86_64/kernel/module.c index 9236b4b59c26..a82e56875f50 100644 --- a/arch/x86_64/kernel/module.c +++ b/arch/x86_64/kernel/module.c @@ -231,3 +231,7 @@ int module_finalize(const Elf_Ehdr *hdr, { return 0; } + +void module_arch_cleanup(struct module *mod) +{ +} diff --git a/include/linux/moduleloader.h b/include/linux/moduleloader.h index 0c9e9a69f8ba..eb1033957486 100644 --- a/include/linux/moduleloader.h +++ b/include/linux/moduleloader.h @@ -41,4 +41,7 @@ int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *mod); +/* Any cleanup needed when module leaves. */ +void module_arch_cleanup(struct module *mod); + #endif diff --git a/kernel/module.c b/kernel/module.c index 06ff9328b30b..4a01db569ac8 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -910,6 +910,9 @@ static void free_module(struct module *mod) list_del(&mod->list); spin_unlock_irq(&modlist_lock); + /* Arch-specific cleanup. */ + module_arch_cleanup(mod); + /* Module unload stuff */ module_unload_free(mod); @@ -1276,6 +1279,7 @@ static struct module *load_module(void __user *umod, mod->module_init = ptr; /* Transfer each section which specifies SHF_ALLOC */ + DEBUGP("final section addresses:\n"); for (i = 0; i < hdr->e_shnum; i++) { void *dest; @@ -1293,6 +1297,7 @@ static struct module *load_module(void __user *umod, sechdrs[i].sh_size); /* Update sh_addr to point to copy in image. */ sechdrs[i].sh_addr = (unsigned long)dest; + DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name); } /* Module has been moved. */ mod = (void *)sechdrs[modindex].sh_addr; -- cgit v1.2.3 From fb7f7773c0d96957ca48b07915252615ef66989e Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 12 May 2003 09:10:13 -0700 Subject: [PATCH] remove devfs_register From: Christoph Hellwig Whee! devfs_register isn't used anymore in the whole tree and with it some other devfs crap. Kill it for good. --- fs/devfs/base.c | 94 +---------------------------------------- include/linux/devfs_fs_kernel.h | 27 ------------ 2 files changed, 1 insertion(+), 120 deletions(-) (limited to 'include') diff --git a/fs/devfs/base.c b/fs/devfs/base.c index fa63dc1820a5..6ca2544a5322 100644 --- a/fs/devfs/base.c +++ b/fs/devfs/base.c @@ -752,6 +752,7 @@ # define DPRINTK(flag, format, args...) #endif +typedef struct devfs_entry *devfs_handle_t; struct directory_type { @@ -1424,98 +1425,6 @@ static void devfsd_notify (struct devfs_entry *de,unsigned short type) current->egid, &fs_info); } - -/** - * devfs_register - Register a device entry. - * @dir: The handle to the parent devfs directory entry. If this is %NULL the - * new name is relative to the root of the devfs. - * @name: The name of the entry. - * @flags: Must be 0 - * @major: The major number. Not needed for regular files. - * @minor: The minor number. Not needed for regular files. - * @mode: The default file mode. - * @ops: The &file_operations or &block_device_operations structure. - * This must not be externally deallocated. - * @info: An arbitrary pointer which will be written to the @private_data - * field of the &file structure passed to the device driver. You can set - * this to whatever you like, and change it once the file is opened (the next - * file opened will not see this change). - * - * On failure %NULL is returned. - */ - -devfs_handle_t devfs_register (devfs_handle_t dir, const char *name, - unsigned int flags, - unsigned int major, unsigned int minor, - umode_t mode, void *ops, void *info) -{ - int err; - dev_t devnum = 0, dev = MKDEV(major, minor); - struct devfs_entry *de; - - /* we don't accept any flags anymore. prototype will change soon. */ - WARN_ON(flags); - WARN_ON(dir); - WARN_ON(!S_ISCHR(mode)); - - if (name == NULL) - { - PRINTK ("(): NULL name pointer\n"); - return NULL; - } - if (ops == NULL) - { - PRINTK ("(%s): NULL ops pointer\n", name); - return NULL; - } - if ( S_ISDIR (mode) ) - { - PRINTK ("(%s): creating directories is not allowed\n", name); - return NULL; - } - if ( S_ISLNK (mode) ) - { - PRINTK ("(%s): creating symlinks is not allowed\n", name); - return NULL; - } - if ( ( de = _devfs_prepare_leaf (&dir, name, mode) ) == NULL ) - { - PRINTK ("(%s): could not prepare leaf\n", name); - if (devnum) devfs_dealloc_devnum (mode, devnum); - return NULL; - } - if (S_ISCHR (mode)) { - de->u.cdev.dev = dev; - de->u.cdev.autogen = devnum != 0; - de->u.cdev.ops = ops; - } else if (S_ISBLK (mode)) { - de->u.bdev.dev = dev; - de->u.cdev.autogen = devnum != 0; - } else { - PRINTK ("(%s): illegal mode: %x\n", name, mode); - devfs_put (de); - devfs_put (dir); - return (NULL); - } - de->info = info; - de->inode.uid = 0; - de->inode.gid = 0; - err = _devfs_append_entry(dir, de, NULL); - if (err) - { - PRINTK ("(%s): could not append to parent, err: %d\n", name, err); - devfs_put (dir); - if (devnum) devfs_dealloc_devnum (mode, devnum); - return NULL; - } - DPRINTK (DEBUG_REGISTER, "(%s): de: %p dir: %p \"%s\" pp: %p\n", - name, de, dir, dir->name, dir->parent); - devfsd_notify (de, DEVFSD_NOTIFY_REGISTERED); - devfs_put (dir); - return de; -} /* End Function devfs_register */ - - int devfs_mk_bdev(dev_t dev, umode_t mode, const char *fmt, ...) { struct devfs_entry *dir = NULL, *de; @@ -1935,7 +1844,6 @@ static int __init devfs_setup (char *str) __setup("devfs=", devfs_setup); EXPORT_SYMBOL(devfs_put); -EXPORT_SYMBOL(devfs_register); EXPORT_SYMBOL(devfs_mk_symlink); EXPORT_SYMBOL(devfs_mk_dir); EXPORT_SYMBOL(devfs_remove); diff --git a/include/linux/devfs_fs_kernel.h b/include/linux/devfs_fs_kernel.h index 34ebe93c6194..f12addd1daeb 100644 --- a/include/linux/devfs_fs_kernel.h +++ b/include/linux/devfs_fs_kernel.h @@ -11,20 +11,7 @@ #define DEVFS_SUPER_MAGIC 0x1373 -#define DEVFS_FL_NONE 0x000 /* This helps to make code more readable - no, it doesn't --hch */ -#define DEVFS_FL_DEFAULT DEVFS_FL_NONE - - -typedef struct devfs_entry * devfs_handle_t; - -struct gendisk; - #ifdef CONFIG_DEVFS_FS -extern devfs_handle_t devfs_register (devfs_handle_t dir, const char *name, - unsigned int flags, - unsigned int major, unsigned int minor, - umode_t mode, void *ops, void *info); extern int devfs_mk_bdev(dev_t dev, umode_t mode, const char *fmt, ...) __attribute__((format (printf, 3, 4))); extern int devfs_mk_cdev(dev_t dev, umode_t mode, const char *fmt, ...) @@ -36,19 +23,8 @@ extern void devfs_remove(const char *fmt, ...) __attribute__((format (printf, 1, 2))); extern int devfs_register_tape(const char *name); extern void devfs_unregister_tape(int num); -extern void devfs_register_partition(struct gendisk *dev, int part); extern void mount_devfs_fs(void); #else /* CONFIG_DEVFS_FS */ -static inline devfs_handle_t devfs_register (devfs_handle_t dir, - const char *name, - unsigned int flags, - unsigned int major, - unsigned int minor, - umode_t mode, - void *ops, void *info) -{ - return NULL; -} static inline int devfs_mk_bdev(dev_t dev, umode_t mode, const char *fmt, ...) { return 0; @@ -75,9 +51,6 @@ static inline int devfs_register_tape (const char *name) static inline void devfs_unregister_tape(int num) { } -static inline void devfs_register_partition(struct gendisk *dev, int part) -{ -} static inline void mount_devfs_fs (void) { return; -- cgit v1.2.3 From a3db5a33a37367163b9ad7b45c7b8378f82e3fb8 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 12 May 2003 09:10:30 -0700 Subject: [PATCH] fat cluster search speedup From: Bjorn Stenberg OGAWA Hirofumi This simple patch makes the linux fat filesystem driver use the next_cluster field in the fat_boot_fsinfo structure. This field is a hint where to start looking for free clusters. Using this field makes a big difference for disks connected over slow links such as USB 1.1. Finding the first free cluster on a 40gig fat-formatted usb disk can today take several minutes. This patch cuts it down to a fraction of a second. Also, commit the next_cluster search hint toand from the superblock in write_super/fill_super. --- fs/fat/inode.c | 1 + fs/fat/misc.c | 17 +++++++++++------ include/linux/msdos_fs.h | 3 +-- 3 files changed, 13 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 866edb62fad5..282c0c22db6f 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -897,6 +897,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, sbi->fsinfo_sector); } else { sbi->free_clusters = CF_LE_L(fsinfo->free_clusters); + sbi->prev_free = CF_LE_L(fsinfo->next_cluster); } brelse(fsinfo_bh); diff --git a/fs/fat/misc.c b/fs/fat/misc.c index f7043d09f086..6e3e86c8899b 100644 --- a/fs/fat/misc.c +++ b/fs/fat/misc.c @@ -74,6 +74,7 @@ void fat_clusters_flush(struct super_block *sb) MSDOS_SB(sb)->fsinfo_sector); } else { fsinfo->free_clusters = CF_LE_L(MSDOS_SB(sb)->free_clusters); + fsinfo->next_cluster = CF_LE_L(MSDOS_SB(sb)->prev_free); mark_buffer_dirty(bh); } brelse(bh); @@ -130,19 +131,23 @@ int fat_add_cluster(struct inode *inode) unlock_fat(sb); return -ENOSPC; } - limit = MSDOS_SB(sb)->clusters; - for (count = 0; count < limit; count++) { - nr = ((count + MSDOS_SB(sb)->prev_free) % limit) + 2; + + limit = MSDOS_SB(sb)->clusters + 2; + nr = MSDOS_SB(sb)->prev_free + 1; + for (count = 0; count < MSDOS_SB(sb)->clusters; count++, nr++) { + nr = nr % limit; + if (nr < 2) + nr = 2; if (fat_access(sb, nr, -1) == FAT_ENT_FREE) break; } - if (count >= limit) { + if (count >= MSDOS_SB(sb)->clusters) { MSDOS_SB(sb)->free_clusters = 0; unlock_fat(sb); return -ENOSPC; } - - MSDOS_SB(sb)->prev_free = (count + MSDOS_SB(sb)->prev_free + 1) % limit; + MSDOS_SB(sb)->prev_free = nr; + fat_access(sb, nr, FAT_ENT_EOF); if (MSDOS_SB(sb)->free_clusters != -1) MSDOS_SB(sb)->free_clusters--; diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h index 2945cb406b64..bd09a8135e79 100644 --- a/include/linux/msdos_fs.h +++ b/include/linux/msdos_fs.h @@ -146,8 +146,7 @@ struct fat_boot_fsinfo { __u32 reserved1[120]; /* Nothing as far as I can tell */ __u32 signature2; /* 0x61417272L */ __u32 free_clusters; /* Free cluster count. -1 if unknown */ - __u32 next_cluster; /* Most recently allocated cluster. - * Unused under Linux. */ + __u32 next_cluster; /* Most recently allocated cluster */ __u32 reserved2[4]; }; -- cgit v1.2.3 From 281df9b372d682a93f1fb4bdd9756d7601d50e0e Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 12 May 2003 09:11:06 -0700 Subject: [PATCH] export cpufreq_driver to fix oops in proc interface From: Zwane Mwaikambo The proc interface has no way of telling wether there is an active cpufreq driver or not. This means that if you don't have a cpufreq supported processor, this will oops in various possible places. --- drivers/cpufreq/proc_intf.c | 3 +++ include/linux/cpufreq.h | 3 +++ kernel/cpufreq.c | 4 +++- 3 files changed, 9 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/drivers/cpufreq/proc_intf.c b/drivers/cpufreq/proc_intf.c index 5845e3404085..253dab930b06 100644 --- a/drivers/cpufreq/proc_intf.c +++ b/drivers/cpufreq/proc_intf.c @@ -209,6 +209,9 @@ static int __init cpufreq_proc_init (void) { struct proc_dir_entry *entry = NULL; + if (!cpufreq_driver) + return -ENODEV; + /* are these acceptable values? */ entry = create_proc_entry("cpufreq", S_IFREG|S_IRUGO|S_IWUSR, &proc_root); diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index e99b9c3c1d01..3dc9062bd414 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -311,4 +311,7 @@ void cpufreq_frequency_table_put_attr(unsigned int cpu); #endif /* CONFIG_CPU_FREQ_TABLE */ +/* Currently exported only for the proc interface, remove when that goes */ +extern struct cpufreq_driver *cpufreq_driver; + #endif /* _LINUX_CPUFREQ_H */ diff --git a/kernel/cpufreq.c b/kernel/cpufreq.c index 913e6b0f56fb..589bf0bf2093 100644 --- a/kernel/cpufreq.c +++ b/kernel/cpufreq.c @@ -29,9 +29,11 @@ * level driver of CPUFreq support, and its locking mutex. * cpu_max_freq is in kHz. */ -static struct cpufreq_driver *cpufreq_driver; +struct cpufreq_driver *cpufreq_driver; static DECLARE_MUTEX (cpufreq_driver_sem); +/* required for the proc interface, remove when that goes away */ +EXPORT_SYMBOL_GPL(cpufreq_driver); /** * Two notifier lists: the "policy" list is involved in the -- cgit v1.2.3 From b5c385359e6452bd63971a35a022e3f71f5246fe Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 12 May 2003 09:11:41 -0700 Subject: [PATCH] exit_mmap() TASK_SIZE fix exit_mmap() currently assumes that the exitting task used virtual address span TASK_SIZE. But on some platforms, TASK_SIZE is variable, based on current->mm. But exit_mmap() can be called from (say) procfs's call to mmput. In which case current->mm has nothing to do with the mm which is being put in mmput(). So rather than assuming that the mm which is being put is current->mm, we need to calculate the virtual span of the mm. Add a new per-arch macro MM_VM_SIZE() for that. Some platforms can currently go BUG over this (where?). sparc64 is safe because our TASK_SIZE is constant. Platforms such as ia64 should stick the VM extent inside of mm_struct, I'd suggest adding it to mm_context_t. 1) TASK_SIZE means what is valid for mmap()'s in the processes address space 2) MM_VM_SIZE means where things might be mapped for a MM, including private implementation-specific areas created by the kernel which the user cannot access --- include/linux/mm.h | 5 +++++ mm/mmap.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/mm.h b/include/linux/mm.h index 6aa89d73f65b..51f5377ec8fc 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -23,8 +23,13 @@ extern int page_cluster; #include #include +#include #include +#ifndef MM_VM_SIZE +#define MM_VM_SIZE(mm) TASK_SIZE +#endif + /* * Linux kernel virtual memory manager primitives. * The idea being to have a "virtual" mm in the same way diff --git a/mm/mmap.c b/mm/mmap.c index c0582bf2256f..f773d3d429b1 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1442,7 +1442,7 @@ void exit_mmap(struct mm_struct *mm) vm_unacct_memory(nr_accounted); BUG_ON(mm->map_count); /* This is just debugging */ clear_page_tables(tlb, FIRST_USER_PGD_NR, USER_PTRS_PER_PGD); - tlb_finish_mmu(tlb, 0, TASK_SIZE); + tlb_finish_mmu(tlb, 0, MM_VM_SIZE(mm)); vma = mm->mmap; mm->mmap = mm->mmap_cache = NULL; -- cgit v1.2.3 From 41541461da07d58d3db0df5218c10ead64882d7a Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 12 May 2003 09:12:07 -0700 Subject: [PATCH] fix for clusterd io_apics From: Keith Mannthey The following is a patch to fix inconsistent use of the function set_ioapic_affinity. In the current kernel it is unclear as to weather the value being passed to the function is a cpu mask or valid apic id. In irq_affinity_write_proc the kernel passes on a cpu mask but the kirqd thread passes on logical apic ids. In flat apic mode this is not an issue because a cpu mask represents the apic value. However in clustered apic mode the cpu mask is very different from the logical apic id. This is an attempt to do the right thing for clustered apics. I clarify that the value being passed to set_ioapic_affinity is a cpu mask not a apicid. Set_ioapic_affinity will do the conversion to logical apic ids. Since many cpu masks don't map to valid apicids in clustered apic mode TARGET_CPUS is used as a default value when such a situation occurs. I think this is a good step in making irq_affinity clustered apic safe. --- arch/i386/kernel/io_apic.c | 29 ++++++++++++------------ include/asm-i386/mach-bigsmp/mach_apic.h | 37 ++++++++++++++++++++++++++++++- include/asm-i386/mach-default/mach_apic.h | 5 +++++ include/asm-i386/mach-numaq/mach_apic.h | 34 ++++++++++++++++++++++++++++ include/asm-i386/mach-summit/mach_apic.h | 37 ++++++++++++++++++++++++++++++- include/asm-i386/mach-visws/mach_apic.h | 4 ++++ 6 files changed, 129 insertions(+), 17 deletions(-) (limited to 'include') diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index d6729a396b63..b5b275e96a8d 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -240,22 +240,22 @@ static void clear_IO_APIC (void) clear_IO_APIC_pin(apic, pin); } -static void set_ioapic_affinity (unsigned int irq, unsigned long mask) +static void set_ioapic_affinity (unsigned int irq, unsigned long cpu_mask) { unsigned long flags; int pin; struct irq_pin_list *entry = irq_2_pin + irq; - - /* - * Only the first 8 bits are valid. - */ - mask = mask << 24; + unsigned int apicid_value; + + apicid_value = cpu_mask_to_apicid(cpu_mask); + /* Prepare to do the io_apic_write */ + apicid_value = apicid_value << 24; spin_lock_irqsave(&ioapic_lock, flags); for (;;) { pin = entry->pin; if (pin == -1) break; - io_apic_write(entry->apic, 0x10 + 1 + pin*2, mask); + io_apic_write(entry->apic, 0x10 + 1 + pin*2, apicid_value); if (!entry->next) break; entry = irq_2_pin + entry->next; @@ -279,7 +279,7 @@ static void set_ioapic_affinity (unsigned int irq, unsigned long mask) extern unsigned long irq_affinity[NR_IRQS]; -static int __cacheline_aligned pending_irq_balance_apicid[NR_IRQS]; +static int __cacheline_aligned pending_irq_balance_cpumask[NR_IRQS]; #define IRQBALANCE_CHECK_ARCH -999 static int irqbalance_disabled = IRQBALANCE_CHECK_ARCH; @@ -356,7 +356,7 @@ static inline void balance_irq(int cpu, int irq) unsigned long flags; spin_lock_irqsave(&desc->lock, flags); - pending_irq_balance_apicid[irq]=cpu_to_logical_apicid(new_cpu); + pending_irq_balance_cpumask[irq] = 1 << new_cpu; spin_unlock_irqrestore(&desc->lock, flags); } } @@ -553,8 +553,7 @@ tryanotherirq: selected_irq, min_loaded); /* mark for change destination */ spin_lock_irqsave(&desc->lock, flags); - pending_irq_balance_apicid[selected_irq] = - cpu_to_logical_apicid(min_loaded); + pending_irq_balance_cpumask[selected_irq] = 1 << min_loaded; spin_unlock_irqrestore(&desc->lock, flags); /* Since we made a change, come back sooner to * check for more variation. @@ -586,7 +585,7 @@ int balanced_irq(void *unused) /* push everything to CPU 0 to give us a starting point. */ for (i = 0 ; i < NR_IRQS ; i++) - pending_irq_balance_apicid[i] = cpu_to_logical_apicid(0); + pending_irq_balance_cpumask[i] = 1; repeat: set_current_state(TASK_INTERRUPTIBLE); @@ -663,9 +662,9 @@ static void set_ioapic_affinity (unsigned int irq, unsigned long mask); static inline void move_irq(int irq) { /* note - we hold the desc->lock */ - if (unlikely(pending_irq_balance_apicid[irq])) { - set_ioapic_affinity(irq, pending_irq_balance_apicid[irq]); - pending_irq_balance_apicid[irq] = 0; + if (unlikely(pending_irq_balance_cpumask[irq])) { + set_ioapic_affinity(irq, pending_irq_balance_cpumask[irq]); + pending_irq_balance_cpumask[irq] = 0; } } diff --git a/include/asm-i386/mach-bigsmp/mach_apic.h b/include/asm-i386/mach-bigsmp/mach_apic.h index 93972fcd768f..7b6435b052f3 100644 --- a/include/asm-i386/mach-bigsmp/mach_apic.h +++ b/include/asm-i386/mach-bigsmp/mach_apic.h @@ -34,10 +34,12 @@ static inline unsigned long check_apicid_used(unsigned long bitmap, int apicid) return 0; } static inline unsigned long check_apicid_present(int bit) -{ +{ return (phys_cpu_present_map & (1 << bit)); } +#define apicid_cluster(apicid) (apicid & 0xF0) + static inline unsigned long calculate_ldr(unsigned long old) { unsigned long id; @@ -134,4 +136,37 @@ static inline unsigned get_apic_id(unsigned long x) #define GET_APIC_ID(x) get_apic_id(x) +static inline unsigned int cpu_mask_to_apicid (unsigned long cpumask) +{ + int num_bits_set; + int cpus_found = 0; + int cpu; + int apicid; + + num_bits_set = hweight32(cpumask); + /* Return id to all */ + if (num_bits_set == 32) + return (int) 0xFF; + /* + * The cpus in the mask must all be on the apic cluster. If are not + * on the same apicid cluster return default value of TARGET_CPUS. + */ + cpu = ffs(cpumask)-1; + apicid = cpu_to_logical_apicid(cpu); + while (cpus_found < num_bits_set) { + if (cpumask & (1 << cpu)) { + int new_apicid = cpu_to_logical_apicid(cpu); + if (apicid_cluster(apicid) != + apicid_cluster(new_apicid)){ + printk ("%s: Not a valid mask!\n",__FUNCTION__); + return TARGET_CPUS; + } + apicid = apicid | new_apicid; + cpus_found++; + } + cpu++; + } + return apicid; +} + #endif /* __ASM_MACH_APIC_H */ diff --git a/include/asm-i386/mach-default/mach_apic.h b/include/asm-i386/mach-default/mach_apic.h index e865f01f5167..ad40d96b3824 100644 --- a/include/asm-i386/mach-default/mach_apic.h +++ b/include/asm-i386/mach-default/mach_apic.h @@ -120,4 +120,9 @@ static inline int apic_id_registered(void) &phys_cpu_present_map)); } +static inline unsigned int cpu_mask_to_apicid (unsigned long cpumask) +{ + return cpumask; +} + #endif /* __ASM_MACH_APIC_H */ diff --git a/include/asm-i386/mach-numaq/mach_apic.h b/include/asm-i386/mach-numaq/mach_apic.h index 54a7c97fe8d1..d5160168908a 100644 --- a/include/asm-i386/mach-numaq/mach_apic.h +++ b/include/asm-i386/mach-numaq/mach_apic.h @@ -17,6 +17,7 @@ #define APIC_BROADCAST_ID 0x0F #define check_apicid_used(bitmap, apicid) ((bitmap) & (1 << (apicid))) #define check_apicid_present(bit) (phys_cpu_present_map & (1 << bit)) +#define apicid_cluster(apicid) (apicid & 0xF0) static inline int apic_id_registered(void) { @@ -115,4 +116,37 @@ static inline unsigned get_apic_id(unsigned long x) #define GET_APIC_ID(x) get_apic_id(x) +static inline unsigned int cpu_mask_to_apicid (unsigned long cpumask) +{ + int num_bits_set; + int cpus_found = 0; + int cpu; + int apicid; + + num_bits_set = hweight32(cpumask); + /* Return id to all */ + if (num_bits_set == 32) + return (int) 0xFF; + /* + * The cpus in the mask must all be on the apic cluster. If are not + * on the same apicid cluster return default value of TARGET_CPUS. + */ + cpu = ffs(cpumask)-1; + apicid = cpu_to_logical_apicid(cpu); + while (cpus_found < num_bits_set) { + if (cpumask & (1 << cpu)) { + int new_apicid = cpu_to_logical_apicid(cpu); + if (apicid_cluster(apicid) != + apicid_cluster(new_apicid)){ + printk ("%s: Not a valid mask!\n",__FUNCTION__); + return TARGET_CPUS; + } + apicid = apicid | new_apicid; + cpus_found++; + } + cpu++; + } + return apicid; +} + #endif /* __ASM_MACH_APIC_H */ diff --git a/include/asm-i386/mach-summit/mach_apic.h b/include/asm-i386/mach-summit/mach_apic.h index ae58d629c9ba..93207f09d43b 100644 --- a/include/asm-i386/mach-summit/mach_apic.h +++ b/include/asm-i386/mach-summit/mach_apic.h @@ -34,7 +34,7 @@ static inline unsigned long target_cpus(void) #define APIC_BROADCAST_ID (0x0F) static inline unsigned long check_apicid_used(unsigned long bitmap, int apicid) -{ +{ return (x86_summit ? 0 : (bitmap & (1 << apicid))); } @@ -44,6 +44,8 @@ static inline unsigned long check_apicid_present(int bit) return (x86_summit ? 1 : (phys_cpu_present_map & (1 << bit))); } +#define apicid_cluster(apicid) (apicid & 0xF0) + extern u8 bios_cpu_apicid[]; static inline void init_apic_ldr(void) @@ -142,4 +144,37 @@ static inline unsigned get_apic_id(unsigned long x) #define GET_APIC_ID(x) get_apic_id(x) +static inline unsigned int cpu_mask_to_apicid (unsigned long cpumask) +{ + int num_bits_set; + int cpus_found = 0; + int cpu; + int apicid; + + num_bits_set = hweight32(cpumask); + /* Return id to all */ + if (num_bits_set == 32) + return (int) 0xFF; + /* + * The cpus in the mask must all be on the apic cluster. If are not + * on the same apicid cluster return default value of TARGET_CPUS. + */ + cpu = ffs(cpumask)-1; + apicid = cpu_to_logical_apicid(cpu); + while (cpus_found < num_bits_set) { + if (cpumask & (1 << cpu)) { + int new_apicid = cpu_to_logical_apicid(cpu); + if (apicid_cluster(apicid) != + apicid_cluster(new_apicid)){ + printk ("%s: Not a valid mask!\n",__FUNCTION__); + return TARGET_CPUS; + } + apicid = apicid | new_apicid; + cpus_found++; + } + cpu++; + } + return apicid; +} + #endif /* __ASM_MACH_APIC_H */ diff --git a/include/asm-i386/mach-visws/mach_apic.h b/include/asm-i386/mach-visws/mach_apic.h index 84047e09ce2b..641c173d4f76 100644 --- a/include/asm-i386/mach-visws/mach_apic.h +++ b/include/asm-i386/mach-visws/mach_apic.h @@ -77,4 +77,8 @@ static inline int check_phys_apicid_present(int boot_cpu_physical_apicid) return test_bit(boot_cpu_physical_apicid, &phys_cpu_present_map); } +static inline unsigned int cpu_mask_to_apicid (unsigned long cpumask) +{ + return cpumask; +} #endif /* __ASM_MACH_APIC_H */ -- cgit v1.2.3 From 699155e3a63c395c1769769a06ad0284db7a95dd Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 12 May 2003 09:13:18 -0700 Subject: [PATCH] htree nfs fix Patch from "Theodore Ts'o" We now use 0x7ffffff as the EOF cookie, because Linux NFS stupidly interprets the cookie (which is supposed to be a bag of bits without necessarily any semantic value) as a signed 64 bit integer, and then converts it to a unsigned integer, and then blows up if it cannot be expressed be expressed as a 32-bit value!! In order to do this, we have to fold the hash value 0x7ffffff into the hash value 0x7ffffffe. This is relatively safe; the only time we will lose if the directory contains filenames that hash to both 0x7ffffffe and 0x7fffffff (under the original hash), and the last directory entry which hashes to 0x7ffffffe is at the end of a leaf block, and the first directory entry which hashes to 0x7fffffff is at the beginning of a leaf block. --- fs/ext3/dir.c | 6 +++--- fs/ext3/hash.c | 5 ++++- include/linux/ext3_fs.h | 2 ++ 3 files changed, 9 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c index 4e73022d7637..2b387b5649e1 100644 --- a/fs/ext3/dir.c +++ b/fs/ext3/dir.c @@ -439,7 +439,7 @@ static int ext3_dx_readdir(struct file * filp, filp->private_data = info; } - if (filp->f_pos == -1) + if (filp->f_pos == EXT3_HTREE_EOF) return 0; /* EOF */ /* Some one has messed with f_pos; reset the world */ @@ -479,7 +479,7 @@ static int ext3_dx_readdir(struct file * filp, if (ret < 0) return ret; if (ret == 0) { - filp->f_pos = -1; + filp->f_pos = EXT3_HTREE_EOF; break; } info->curr_node = rb_first(&info->root); @@ -494,7 +494,7 @@ static int ext3_dx_readdir(struct file * filp, info->curr_node = rb_next(info->curr_node); if (!info->curr_node) { if (info->next_hash == ~0) { - filp->f_pos = -1; + filp->f_pos = EXT3_HTREE_EOF; break; } info->curr_hash = info->next_hash; diff --git a/fs/ext3/hash.c b/fs/ext3/hash.c index 2025354b85de..d00d658b1cfb 100644 --- a/fs/ext3/hash.c +++ b/fs/ext3/hash.c @@ -209,7 +209,10 @@ int ext3fs_dirhash(const char *name, int len, struct dx_hash_info *hinfo) hinfo->hash = 0; return -1; } - hinfo->hash = hash & ~1; + hash = hash & ~1; + if (hash == (EXT3_HTREE_EOF << 1)) + hash = (EXT3_HTREE_EOF-1) << 1; + hinfo->hash = hash; hinfo->minor_hash = minor_hash; return 0; } diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h index b3da32479e13..c2f36c9d8022 100644 --- a/include/linux/ext3_fs.h +++ b/include/linux/ext3_fs.h @@ -625,6 +625,8 @@ struct dx_hash_info u32 *seed; }; +#define EXT3_HTREE_EOF 0x7fffffff + #ifdef __KERNEL__ /* * Control parameters used by ext3_htree_next_block -- cgit v1.2.3