]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branch 'proc' of git://git.kernel.org/pub/scm/linux/kernel/git/adobriyan/proc
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 23 Oct 2008 19:04:37 +0000 (12:04 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 23 Oct 2008 19:04:37 +0000 (12:04 -0700)
* 'proc' of git://git.kernel.org/pub/scm/linux/kernel/git/adobriyan/proc: (35 commits)
  proc: remove fs/proc/proc_misc.c
  proc: move /proc/vmcore creation to fs/proc/vmcore.c
  proc: move pagecount stuff to fs/proc/page.c
  proc: move all /proc/kcore stuff to fs/proc/kcore.c
  proc: move /proc/schedstat boilerplate to kernel/sched_stats.h
  proc: move /proc/modules boilerplate to kernel/module.c
  proc: move /proc/diskstats boilerplate to block/genhd.c
  proc: move /proc/zoneinfo boilerplate to mm/vmstat.c
  proc: move /proc/vmstat boilerplate to mm/vmstat.c
  proc: move /proc/pagetypeinfo boilerplate to mm/vmstat.c
  proc: move /proc/buddyinfo boilerplate to mm/vmstat.c
  proc: move /proc/vmallocinfo to mm/vmalloc.c
  proc: move /proc/slabinfo boilerplate to mm/slub.c, mm/slab.c
  proc: move /proc/slab_allocators boilerplate to mm/slab.c
  proc: move /proc/interrupts boilerplate code to fs/proc/interrupts.c
  proc: move /proc/stat to fs/proc/stat.c
  proc: move rest of /proc/partitions code to block/genhd.c
  proc: move /proc/cpuinfo code to fs/proc/cpuinfo.c
  proc: move /proc/devices code to fs/proc/devices.c
  proc: move rest of /proc/locks to fs/locks.c
  ...

1  2 
arch/x86/include/asm/pgtable.h
fs/locks.c
fs/proc/proc_sysctl.c
include/linux/fs.h
include/linux/sched.h
kernel/module.c
kernel/sched.c
kernel/sched_stats.h

index fb7d1e9985b5a4ea4940dab4ee63c9777ec174ed,a3dda6d615be223d1275eb8eecd89bcbc2a3b354..c012f3b11671574150720dcaee023780cd79d905
@@@ -1,5 -1,5 +1,5 @@@
 -#ifndef ASM_X86__PGTABLE_H
 -#define ASM_X86__PGTABLE_H
 +#ifndef _ASM_X86_PGTABLE_H
 +#define _ASM_X86_PGTABLE_H
  
  #define FIRST_USER_ADDRESS    0
  
@@@ -348,7 -348,8 +348,8 @@@ static inline void native_pagetable_set
  static inline void native_pagetable_setup_done(pgd_t *base) {}
  #endif
  
- extern int arch_report_meminfo(char *page);
+ struct seq_file;
+ extern void arch_report_meminfo(struct seq_file *m);
  
  #ifdef CONFIG_PARAVIRT
  #include <asm/paravirt.h>
@@@ -558,4 -559,4 +559,4 @@@ static inline void clone_pgd_range(pgd_
  #include <asm-generic/pgtable.h>
  #endif        /* __ASSEMBLY__ */
  
 -#endif /* ASM_X86__PGTABLE_H */
 +#endif /* _ASM_X86_PGTABLE_H */
diff --combined fs/locks.c
index 20457486d6b2a95e67783f220b89f8cb19e22d3e,90e87f57b331ad8df85e6645b2d0d0fde631414f..09062e3ff104d7222d4725d757c5493da3ad68fa
@@@ -1580,8 -1580,7 +1580,8 @@@ asmlinkage long sys_flock(unsigned int 
        cmd &= ~LOCK_NB;
        unlock = (cmd == LOCK_UN);
  
 -      if (!unlock && !(cmd & LOCK_MAND) && !(filp->f_mode & 3))
 +      if (!unlock && !(cmd & LOCK_MAND) &&
 +          !(filp->f_mode & (FMODE_READ|FMODE_WRITE)))
                goto out_putf;
  
        error = flock_make_lock(filp, &lock, cmd);
@@@ -2079,6 -2078,7 +2079,7 @@@ int vfs_cancel_lock(struct file *filp, 
  EXPORT_SYMBOL_GPL(vfs_cancel_lock);
  
  #ifdef CONFIG_PROC_FS
+ #include <linux/proc_fs.h>
  #include <linux/seq_file.h>
  
  static void lock_get_status(struct seq_file *f, struct file_lock *fl,
@@@ -2184,12 -2184,31 +2185,31 @@@ static void locks_stop(struct seq_file 
        unlock_kernel();
  }
  
- struct seq_operations locks_seq_operations = {
+ static const struct seq_operations locks_seq_operations = {
        .start  = locks_start,
        .next   = locks_next,
        .stop   = locks_stop,
        .show   = locks_show,
  };
+ static int locks_open(struct inode *inode, struct file *filp)
+ {
+       return seq_open(filp, &locks_seq_operations);
+ }
+ static const struct file_operations proc_locks_operations = {
+       .open           = locks_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+ };
+ static int __init proc_locks_init(void)
+ {
+       proc_create("locks", 0, NULL, &proc_locks_operations);
+       return 0;
+ }
+ module_init(proc_locks_init);
  #endif
  
  /**
diff --combined fs/proc/proc_sysctl.c
index 7b997754a25e705ddb41009b0741ddad3c3799a2,41b5063e28d1e72ee45ad971eb5f0d2ab0ffd139..94fcfff6863a5976965b8d4253ff3ad1ac45386b
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * /proc/sys support
   */
+ #include <linux/init.h>
  #include <linux/sysctl.h>
  #include <linux/proc_fs.h>
  #include <linux/security.h>
@@@ -298,19 -298,13 +298,19 @@@ static int proc_sys_permission(struct i
         * sysctl entries that are not writeable,
         * are _NOT_ writeable, capabilities or not.
         */
 -      struct ctl_table_header *head = grab_header(inode);
 -      struct ctl_table *table = PROC_I(inode)->sysctl_entry;
 +      struct ctl_table_header *head;
 +      struct ctl_table *table;
        int error;
  
 +      /* Executable files are not allowed under /proc/sys/ */
 +      if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))
 +              return -EACCES;
 +
 +      head = grab_header(inode);
        if (IS_ERR(head))
                return PTR_ERR(head);
  
 +      table = PROC_I(inode)->sysctl_entry;
        if (!table) /* global root - r-xr-xr-x */
                error = mask & MAY_WRITE ? -EACCES : 0;
        else /* Use the permissions on the sysctl table entry */
@@@ -359,7 -353,6 +359,7 @@@ static const struct file_operations pro
  
  static const struct file_operations proc_sys_dir_file_operations = {
        .readdir        = proc_sys_readdir,
 +      .llseek         = generic_file_llseek,
  };
  
  static const struct inode_operations proc_sys_inode_operations = {
@@@ -402,7 -395,7 +402,7 @@@ static struct dentry_operations proc_sy
        .d_compare      = proc_sys_compare,
  };
  
- int proc_sys_init(void)
+ int __init proc_sys_init(void)
  {
        struct proc_dir_entry *proc_sys_root;
  
diff --combined include/linux/fs.h
index 43659ae52e4d22dec1d90e8db1f61a920414d5f6,024049543ae126335f21b796940a8cddd662a571..5b248d61430c92de2db9df74b6825fefa30fb710
@@@ -63,23 -63,18 +63,23 @@@ extern int dir_notify_enable
  #define MAY_ACCESS 16
  #define MAY_OPEN 32
  
 -#define FMODE_READ 1
 -#define FMODE_WRITE 2
 +#define FMODE_READ ((__force fmode_t)1)
 +#define FMODE_WRITE ((__force fmode_t)2)
  
  /* Internal kernel extensions */
 -#define FMODE_LSEEK   4
 -#define FMODE_PREAD   8
 +#define FMODE_LSEEK   ((__force fmode_t)4)
 +#define FMODE_PREAD   ((__force fmode_t)8)
  #define FMODE_PWRITE  FMODE_PREAD     /* These go hand in hand */
  
  /* File is being opened for execution. Primary users of this flag are
     distributed filesystems that can use it to achieve correct ETXTBUSY
     behavior for cross-node execution/opening_for_writing of files */
 -#define FMODE_EXEC    16
 +#define FMODE_EXEC    ((__force fmode_t)16)
 +
 +#define FMODE_NDELAY  ((__force fmode_t)32)
 +#define FMODE_EXCL    ((__force fmode_t)64)
 +#define FMODE_WRITE_IOCTL     ((__force fmode_t)128)
 +#define FMODE_NDELAY_NOW      ((__force fmode_t)256)
  
  #define RW_MASK               1
  #define RWA_MASK      2
  /*
   * Superblock flags that can be altered by MS_REMOUNT
   */
 -#define MS_RMT_MASK   (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK)
 +#define MS_RMT_MASK   (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION)
  
  /*
   * Old magic mount flag and mask
@@@ -830,7 -825,7 +830,7 @@@ struct file 
        const struct file_operations    *f_op;
        atomic_long_t           f_count;
        unsigned int            f_flags;
 -      mode_t                  f_mode;
 +      fmode_t                 f_mode;
        loff_t                  f_pos;
        struct fown_struct      f_owner;
        unsigned int            f_uid, f_gid;
@@@ -1042,7 -1037,6 +1042,6 @@@ extern int vfs_setlease(struct file *, 
  extern int lease_modify(struct file_lock **, int);
  extern int lock_may_read(struct inode *, loff_t start, unsigned long count);
  extern int lock_may_write(struct inode *, loff_t start, unsigned long count);
- extern struct seq_operations locks_seq_operations;
  #else /* !CONFIG_FILE_LOCKING */
  #define fcntl_getlk(a, b) ({ -EINVAL; })
  #define fcntl_setlk(a, b, c, d) ({ -EACCES; })
@@@ -1157,7 -1151,6 +1156,7 @@@ struct super_block 
        char s_id[32];                          /* Informational name */
  
        void                    *s_fs_info;     /* Filesystem private info */
 +      fmode_t                 s_mode;
  
        /*
         * The next field is for VFS *only*. No filesystems have any business
@@@ -1272,7 -1265,20 +1271,7 @@@ int generic_osync_inode(struct inode *
   * to have different dirent layouts depending on the binary type.
   */
  typedef int (*filldir_t)(void *, const char *, int, loff_t, u64, unsigned);
 -
 -struct block_device_operations {
 -      int (*open) (struct inode *, struct file *);
 -      int (*release) (struct inode *, struct file *);
 -      int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long);
 -      long (*unlocked_ioctl) (struct file *, unsigned, unsigned long);
 -      long (*compat_ioctl) (struct file *, unsigned, unsigned long);
 -      int (*direct_access) (struct block_device *, sector_t,
 -                                              void **, unsigned long *);
 -      int (*media_changed) (struct gendisk *);
 -      int (*revalidate_disk) (struct gendisk *);
 -      int (*getgeo)(struct block_device *, struct hd_geometry *);
 -      struct module *owner;
 -};
 +struct block_device_operations;
  
  /* These macros are for out of kernel modules to test that
   * the kernel supports the unlocked_ioctl and compat_ioctl
@@@ -1586,6 -1592,7 +1585,6 @@@ extern int get_sb_pseudo(struct file_sy
        struct vfsmount *mnt);
  extern int simple_set_mnt(struct vfsmount *mnt, struct super_block *sb);
  int __put_super_and_need_restart(struct super_block *sb);
 -void unnamed_dev_init(void);
  
  /* Alas, no aliases. Too much hassle with bringing module.h everywhere */
  #define fops_get(fops) \
@@@ -1706,7 -1713,7 +1705,7 @@@ extern struct block_device *bdget(dev_t
  extern void bd_set_size(struct block_device *, loff_t size);
  extern void bd_forget(struct inode *inode);
  extern void bdput(struct block_device *);
 -extern struct block_device *open_by_devnum(dev_t, unsigned);
 +extern struct block_device *open_by_devnum(dev_t, fmode_t);
  #else
  static inline void bd_forget(struct inode *inode) {}
  #endif
@@@ -1716,10 -1723,13 +1715,10 @@@ extern const struct file_operations bad
  extern const struct file_operations def_fifo_fops;
  #ifdef CONFIG_BLOCK
  extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long);
 -extern int blkdev_ioctl(struct inode *, struct file *, unsigned, unsigned long);
 -extern int blkdev_driver_ioctl(struct inode *inode, struct file *file,
 -                             struct gendisk *disk, unsigned cmd,
 -                             unsigned long arg);
 +extern int blkdev_ioctl(struct block_device *, fmode_t, unsigned, unsigned long);
  extern long compat_blkdev_ioctl(struct file *, unsigned, unsigned long);
 -extern int blkdev_get(struct block_device *, mode_t, unsigned);
 -extern int blkdev_put(struct block_device *);
 +extern int blkdev_get(struct block_device *, fmode_t);
 +extern int blkdev_put(struct block_device *, fmode_t);
  extern int bd_claim(struct block_device *, void *);
  extern void bd_release(struct block_device *);
  #ifdef CONFIG_SYSFS
@@@ -1750,10 -1760,9 +1749,10 @@@ extern void chrdev_show(struct seq_fil
  extern const char *__bdevname(dev_t, char *buffer);
  extern const char *bdevname(struct block_device *bdev, char *buffer);
  extern struct block_device *lookup_bdev(const char *);
 -extern struct block_device *open_bdev_excl(const char *, int, void *);
 -extern void close_bdev_excl(struct block_device *);
 +extern struct block_device *open_bdev_exclusive(const char *, fmode_t, void *);
 +extern void close_bdev_exclusive(struct block_device *, fmode_t);
  extern void blkdev_show(struct seq_file *,off_t);
 +
  #else
  #define BLKDEV_MAJOR_HASH_SIZE        0
  #endif
@@@ -1842,11 -1851,6 +1841,11 @@@ extern int inode_permission(struct inod
  extern int generic_permission(struct inode *, int,
                int (*check_acl)(struct inode *, int));
  
 +static inline bool execute_ok(struct inode *inode)
 +{
 +      return (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode);
 +}
 +
  extern int get_write_access(struct inode *);
  extern int deny_write_access(struct file *);
  static inline void put_write_access(struct inode * inode)
diff --combined include/linux/sched.h
index 5ca620573d47c35c707b115cdb44ca2fb243d519,7f60cb9b53cb99aa1063de3fe3d8240a407878a4..8478f334d73293473199f6d97a6cc8aabb2d7521
@@@ -287,6 -287,7 +287,6 @@@ extern void trap_init(void)
  extern void account_process_tick(struct task_struct *task, int user);
  extern void update_process_times(int user);
  extern void scheduler_tick(void);
 -extern void hrtick_resched(void);
  
  extern void sched_show_task(struct task_struct *p);
  
@@@ -680,10 -681,6 +680,6 @@@ struct sched_info 
  };
  #endif /* defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) */
  
- #ifdef CONFIG_SCHEDSTATS
- extern const struct file_operations proc_schedstat_operations;
- #endif /* CONFIG_SCHEDSTATS */
  #ifdef CONFIG_TASK_DELAY_ACCT
  struct task_delay_info {
        spinlock_t      lock;
@@@ -1345,12 -1342,6 +1341,12 @@@ struct task_struct 
        int latency_record_count;
        struct latency_record latency_record[LT_SAVECOUNT];
  #endif
 +      /*
 +       * time slack values; these are used to round up poll() and
 +       * select() etc timeout values. These are in nanoseconds.
 +       */
 +      unsigned long timer_slack_ns;
 +      unsigned long default_timer_slack_ns;
  };
  
  /*
@@@ -1670,7 -1661,6 +1666,7 @@@ extern unsigned int sysctl_sched_featur
  extern unsigned int sysctl_sched_migration_cost;
  extern unsigned int sysctl_sched_nr_migrate;
  extern unsigned int sysctl_sched_shares_ratelimit;
 +extern unsigned int sysctl_sched_shares_thresh;
  
  int sched_nr_latency_handler(struct ctl_table *table, int write,
                struct file *file, void __user *buffer, size_t *length,
diff --combined kernel/module.c
index c0f1826e2d9e1cc3094060411f44b4178d9f38b5,6fded84d702936789f74443b7ac28caeaa827945..1f4cc00e0c200b7c69272694d121558fd6a10d06
  #include <linux/moduleloader.h>
  #include <linux/init.h>
  #include <linux/kallsyms.h>
+ #include <linux/fs.h>
  #include <linux/sysfs.h>
  #include <linux/kernel.h>
  #include <linux/slab.h>
  #include <linux/vmalloc.h>
  #include <linux/elf.h>
+ #include <linux/proc_fs.h>
  #include <linux/seq_file.h>
  #include <linux/syscalls.h>
  #include <linux/fcntl.h>
@@@ -42,7 -44,6 +44,7 @@@
  #include <linux/string.h>
  #include <linux/mutex.h>
  #include <linux/unwind.h>
 +#include <linux/rculist.h>
  #include <asm/uaccess.h>
  #include <asm/cacheflush.h>
  #include <linux/license.h>
@@@ -64,7 -65,7 +66,7 @@@
  #define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1))
  
  /* List of modules, protected by module_mutex or preempt_disable
 - * (add/delete uses stop_machine). */
 + * (delete uses stop_machine/add uses RCU list operations). */
  static DEFINE_MUTEX(module_mutex);
  static LIST_HEAD(modules);
  
@@@ -133,29 -134,6 +135,29 @@@ static unsigned int find_sec(Elf_Ehdr *
        return 0;
  }
  
 +/* Find a module section, or NULL. */
 +static void *section_addr(Elf_Ehdr *hdr, Elf_Shdr *shdrs,
 +                        const char *secstrings, const char *name)
 +{
 +      /* Section 0 has sh_addr 0. */
 +      return (void *)shdrs[find_sec(hdr, shdrs, secstrings, name)].sh_addr;
 +}
 +
 +/* Find a module section, or NULL.  Fill in number of "objects" in section. */
 +static void *section_objs(Elf_Ehdr *hdr,
 +                        Elf_Shdr *sechdrs,
 +                        const char *secstrings,
 +                        const char *name,
 +                        size_t object_size,
 +                        unsigned int *num)
 +{
 +      unsigned int sec = find_sec(hdr, sechdrs, secstrings, name);
 +
 +      /* Section 0 has sh_addr 0 and sh_size 0. */
 +      *num = sechdrs[sec].sh_size / object_size;
 +      return (void *)sechdrs[sec].sh_addr;
 +}
 +
  /* Provided by the linker */
  extern const struct kernel_symbol __start___ksymtab[];
  extern const struct kernel_symbol __stop___ksymtab[];
@@@ -242,7 -220,7 +244,7 @@@ static bool each_symbol(bool (*fn)(cons
        if (each_symbol_in_section(arr, ARRAY_SIZE(arr), NULL, fn, data))
                return true;
  
 -      list_for_each_entry(mod, &modules, list) {
 +      list_for_each_entry_rcu(mod, &modules, list) {
                struct symsearch arr[] = {
                        { mod->syms, mod->syms + mod->num_syms, mod->crcs,
                          NOT_GPL_ONLY, false },
@@@ -1417,6 -1395,17 +1419,6 @@@ static void mod_kobject_remove(struct m
        mod_sysfs_fini(mod);
  }
  
 -/*
 - * link the module with the whole machine is stopped with interrupts off
 - * - this defends against kallsyms not taking locks
 - */
 -static int __link_module(void *_mod)
 -{
 -      struct module *mod = _mod;
 -      list_add(&mod->list, &modules);
 -      return 0;
 -}
 -
  /*
   * unlink the module with the whole machine is stopped with interrupts off
   * - this defends against kallsyms not taking locks
@@@ -1802,20 -1791,32 +1804,20 @@@ static inline void add_kallsyms(struct 
  }
  #endif /* CONFIG_KALLSYMS */
  
 -#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG
 -static void dynamic_printk_setup(Elf_Shdr *sechdrs, unsigned int verboseindex)
 +static void dynamic_printk_setup(struct mod_debug *debug, unsigned int num)
  {
 -      struct mod_debug *debug_info;
 -      unsigned long pos, end;
 -      unsigned int num_verbose;
 -
 -      pos = sechdrs[verboseindex].sh_addr;
 -      num_verbose = sechdrs[verboseindex].sh_size /
 -                              sizeof(struct mod_debug);
 -      end = pos + (num_verbose * sizeof(struct mod_debug));
 +#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG
 +      unsigned int i;
  
 -      for (; pos < end; pos += sizeof(struct mod_debug)) {
 -              debug_info = (struct mod_debug *)pos;
 -              register_dynamic_debug_module(debug_info->modname,
 -                      debug_info->type, debug_info->logical_modname,
 -                      debug_info->flag_names, debug_info->hash,
 -                      debug_info->hash2);
 +      for (i = 0; i < num; i++) {
 +              register_dynamic_debug_module(debug[i].modname,
 +                                            debug[i].type,
 +                                            debug[i].logical_modname,
 +                                            debug[i].flag_names,
 +                                            debug[i].hash, debug[i].hash2);
        }
 -}
 -#else
 -static inline void dynamic_printk_setup(Elf_Shdr *sechdrs,
 -                                      unsigned int verboseindex)
 -{
 -}
  #endif /* CONFIG_DYNAMIC_PRINTK_DEBUG */
 +}
  
  static void *module_alloc_update_bounds(unsigned long size)
  {
@@@ -1844,14 -1845,37 +1846,14 @@@ static noinline struct module *load_mod
        unsigned int i;
        unsigned int symindex = 0;
        unsigned int strindex = 0;
 -      unsigned int setupindex;
 -      unsigned int exindex;
 -      unsigned int exportindex;
 -      unsigned int modindex;
 -      unsigned int obsparmindex;
 -      unsigned int infoindex;
 -      unsigned int gplindex;
 -      unsigned int crcindex;
 -      unsigned int gplcrcindex;
 -      unsigned int versindex;
 -      unsigned int pcpuindex;
 -      unsigned int gplfutureindex;
 -      unsigned int gplfuturecrcindex;
 +      unsigned int modindex, versindex, infoindex, pcpuindex;
        unsigned int unwindex = 0;
 -#ifdef CONFIG_UNUSED_SYMBOLS
 -      unsigned int unusedindex;
 -      unsigned int unusedcrcindex;
 -      unsigned int unusedgplindex;
 -      unsigned int unusedgplcrcindex;
 -#endif
 -      unsigned int markersindex;
 -      unsigned int markersstringsindex;
 -      unsigned int verboseindex;
 -      unsigned int tracepointsindex;
 -      unsigned int tracepointsstringsindex;
 -      unsigned int mcountindex;
 +      unsigned int num_kp, num_mcount;
 +      struct kernel_param *kp;
        struct module *mod;
        long err = 0;
        void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
 -      void *mseg;
 -      struct exception_table_entry *extable;
 +      unsigned long *mseg;
        mm_segment_t old_fs;
  
        DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
                err = -ENOEXEC;
                goto free_hdr;
        }
 +      /* This is temporary: point mod into copy of data. */
        mod = (void *)sechdrs[modindex].sh_addr;
  
        if (symindex == 0) {
                goto free_hdr;
        }
  
 -      /* Optional sections */
 -      exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab");
 -      gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl");
 -      gplfutureindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl_future");
 -      crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab");
 -      gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl");
 -      gplfuturecrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl_future");
 -#ifdef CONFIG_UNUSED_SYMBOLS
 -      unusedindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused");
 -      unusedgplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused_gpl");
 -      unusedcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_unused");
 -      unusedgplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_unused_gpl");
 -#endif
 -      setupindex = find_sec(hdr, sechdrs, secstrings, "__param");
 -      exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table");
 -      obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm");
        versindex = find_sec(hdr, sechdrs, secstrings, "__versions");
        infoindex = find_sec(hdr, sechdrs, secstrings, ".modinfo");
        pcpuindex = find_pcpusec(hdr, sechdrs, secstrings);
        if (err < 0)
                goto cleanup;
  
 -      /* Set up EXPORTed & EXPORT_GPLed symbols (section 0 is 0 length) */
 -      mod->num_syms = sechdrs[exportindex].sh_size / sizeof(*mod->syms);
 -      mod->syms = (void *)sechdrs[exportindex].sh_addr;
 -      if (crcindex)
 -              mod->crcs = (void *)sechdrs[crcindex].sh_addr;
 -      mod->num_gpl_syms = sechdrs[gplindex].sh_size / sizeof(*mod->gpl_syms);
 -      mod->gpl_syms = (void *)sechdrs[gplindex].sh_addr;
 -      if (gplcrcindex)
 -              mod->gpl_crcs = (void *)sechdrs[gplcrcindex].sh_addr;
 -      mod->num_gpl_future_syms = sechdrs[gplfutureindex].sh_size /
 -                                      sizeof(*mod->gpl_future_syms);
 -      mod->gpl_future_syms = (void *)sechdrs[gplfutureindex].sh_addr;
 -      if (gplfuturecrcindex)
 -              mod->gpl_future_crcs = (void *)sechdrs[gplfuturecrcindex].sh_addr;
 +      /* Now we've got everything in the final locations, we can
 +       * find optional sections. */
 +      kp = section_objs(hdr, sechdrs, secstrings, "__param", sizeof(*kp),
 +                        &num_kp);
 +      mod->syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab",
 +                               sizeof(*mod->syms), &mod->num_syms);
 +      mod->crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab");
 +      mod->gpl_syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab_gpl",
 +                                   sizeof(*mod->gpl_syms),
 +                                   &mod->num_gpl_syms);
 +      mod->gpl_crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab_gpl");
 +      mod->gpl_future_syms = section_objs(hdr, sechdrs, secstrings,
 +                                          "__ksymtab_gpl_future",
 +                                          sizeof(*mod->gpl_future_syms),
 +                                          &mod->num_gpl_future_syms);
 +      mod->gpl_future_crcs = section_addr(hdr, sechdrs, secstrings,
 +                                          "__kcrctab_gpl_future");
  
  #ifdef CONFIG_UNUSED_SYMBOLS
 -      mod->num_unused_syms = sechdrs[unusedindex].sh_size /
 -                                      sizeof(*mod->unused_syms);
 -      mod->num_unused_gpl_syms = sechdrs[unusedgplindex].sh_size /
 -                                      sizeof(*mod->unused_gpl_syms);
 -      mod->unused_syms = (void *)sechdrs[unusedindex].sh_addr;
 -      if (unusedcrcindex)
 -              mod->unused_crcs = (void *)sechdrs[unusedcrcindex].sh_addr;
 -      mod->unused_gpl_syms = (void *)sechdrs[unusedgplindex].sh_addr;
 -      if (unusedgplcrcindex)
 -              mod->unused_gpl_crcs
 -                      = (void *)sechdrs[unusedgplcrcindex].sh_addr;
 +      mod->unused_syms = section_objs(hdr, sechdrs, secstrings,
 +                                      "__ksymtab_unused",
 +                                      sizeof(*mod->unused_syms),
 +                                      &mod->num_unused_syms);
 +      mod->unused_crcs = section_addr(hdr, sechdrs, secstrings,
 +                                      "__kcrctab_unused");
 +      mod->unused_gpl_syms = section_objs(hdr, sechdrs, secstrings,
 +                                          "__ksymtab_unused_gpl",
 +                                          sizeof(*mod->unused_gpl_syms),
 +                                          &mod->num_unused_gpl_syms);
 +      mod->unused_gpl_crcs = section_addr(hdr, sechdrs, secstrings,
 +                                          "__kcrctab_unused_gpl");
 +#endif
 +
 +#ifdef CONFIG_MARKERS
 +      mod->markers = section_objs(hdr, sechdrs, secstrings, "__markers",
 +                                  sizeof(*mod->markers), &mod->num_markers);
 +#endif
 +#ifdef CONFIG_TRACEPOINTS
 +      mod->tracepoints = section_objs(hdr, sechdrs, secstrings,
 +                                      "__tracepoints",
 +                                      sizeof(*mod->tracepoints),
 +                                      &mod->num_tracepoints);
  #endif
  
  #ifdef CONFIG_MODVERSIONS
 -      if ((mod->num_syms && !crcindex)
 -          || (mod->num_gpl_syms && !gplcrcindex)
 -          || (mod->num_gpl_future_syms && !gplfuturecrcindex)
 +      if ((mod->num_syms && !mod->crcs)
 +          || (mod->num_gpl_syms && !mod->gpl_crcs)
 +          || (mod->num_gpl_future_syms && !mod->gpl_future_crcs)
  #ifdef CONFIG_UNUSED_SYMBOLS
 -          || (mod->num_unused_syms && !unusedcrcindex)
 -          || (mod->num_unused_gpl_syms && !unusedgplcrcindex)
 +          || (mod->num_unused_syms && !mod->unused_crcs)
 +          || (mod->num_unused_gpl_syms && !mod->unused_gpl_crcs)
  #endif
                ) {
                printk(KERN_WARNING "%s: No versions for exported symbols.\n", mod->name);
                        goto cleanup;
        }
  #endif
 -      markersindex = find_sec(hdr, sechdrs, secstrings, "__markers");
 -      markersstringsindex = find_sec(hdr, sechdrs, secstrings,
 -                                      "__markers_strings");
 -      verboseindex = find_sec(hdr, sechdrs, secstrings, "__verbose");
 -      tracepointsindex = find_sec(hdr, sechdrs, secstrings, "__tracepoints");
 -      tracepointsstringsindex = find_sec(hdr, sechdrs, secstrings,
 -                                      "__tracepoints_strings");
 -
 -      mcountindex = find_sec(hdr, sechdrs, secstrings,
 -                             "__mcount_loc");
  
        /* Now do relocations. */
        for (i = 1; i < hdr->e_shnum; i++) {
                if (err < 0)
                        goto cleanup;
        }
 -#ifdef CONFIG_MARKERS
 -      mod->markers = (void *)sechdrs[markersindex].sh_addr;
 -      mod->num_markers =
 -              sechdrs[markersindex].sh_size / sizeof(*mod->markers);
 -#endif
 -#ifdef CONFIG_TRACEPOINTS
 -      mod->tracepoints = (void *)sechdrs[tracepointsindex].sh_addr;
 -      mod->num_tracepoints =
 -              sechdrs[tracepointsindex].sh_size / sizeof(*mod->tracepoints);
 -#endif
 -
  
          /* Find duplicate symbols */
        err = verify_export_symbols(mod);
 -
        if (err < 0)
                goto cleanup;
  
        /* Set up and sort exception table */
 -      mod->num_exentries = sechdrs[exindex].sh_size / sizeof(*mod->extable);
 -      mod->extable = extable = (void *)sechdrs[exindex].sh_addr;
 -      sort_extable(extable, extable + mod->num_exentries);
 +      mod->extable = section_objs(hdr, sechdrs, secstrings, "__ex_table",
 +                                  sizeof(*mod->extable), &mod->num_exentries);
 +      sort_extable(mod->extable, mod->extable + mod->num_exentries);
  
        /* Finally, copy percpu area over. */
        percpu_modcopy(mod->percpu, (void *)sechdrs[pcpuindex].sh_addr,
        add_kallsyms(mod, sechdrs, symindex, strindex, secstrings);
  
        if (!mod->taints) {
 +              struct mod_debug *debug;
 +              unsigned int num_debug;
 +
  #ifdef CONFIG_MARKERS
                marker_update_probe_range(mod->markers,
                        mod->markers + mod->num_markers);
  #endif
 -      dynamic_printk_setup(sechdrs, verboseindex);
 +              debug = section_objs(hdr, sechdrs, secstrings, "__verbose",
 +                                   sizeof(*debug), &num_debug);
 +              dynamic_printk_setup(debug, num_debug);
 +
  #ifdef CONFIG_TRACEPOINTS
                tracepoint_update_probe_range(mod->tracepoints,
                        mod->tracepoints + mod->num_tracepoints);
        }
  
        /* sechdrs[0].sh_size is always zero */
 -      mseg = (void *)sechdrs[mcountindex].sh_addr;
 -      ftrace_init_module(mseg, mseg + sechdrs[mcountindex].sh_size);
 +      mseg = section_objs(hdr, sechdrs, secstrings, "__mcount_loc",
 +                          sizeof(*mseg), &num_mcount);
 +      ftrace_init_module(mseg, mseg + num_mcount);
  
        err = module_finalize(hdr, sechdrs, mod);
        if (err < 0)
        set_fs(old_fs);
  
        mod->args = args;
 -      if (obsparmindex)
 +      if (section_addr(hdr, sechdrs, secstrings, "__obsparm"))
                printk(KERN_WARNING "%s: Ignoring obsolete parameters\n",
                       mod->name);
  
        /* Now sew it into the lists so we can get lockdep and oops
 -         * info during argument parsing.  Noone should access us, since
 -         * strong_try_module_get() will fail. */
 -      stop_machine(__link_module, mod, NULL);
 -
 -      /* Size of section 0 is 0, so this works well if no params */
 -      err = parse_args(mod->name, mod->args,
 -                       (struct kernel_param *)
 -                       sechdrs[setupindex].sh_addr,
 -                       sechdrs[setupindex].sh_size
 -                       / sizeof(struct kernel_param),
 -                       NULL);
 +       * info during argument parsing.  Noone should access us, since
 +       * strong_try_module_get() will fail.
 +       * lockdep/oops can run asynchronous, so use the RCU list insertion
 +       * function to insert in a way safe to concurrent readers.
 +       * The mutex protects against concurrent writers.
 +       */
 +      list_add_rcu(&mod->list, &modules);
 +
 +      err = parse_args(mod->name, mod->args, kp, num_kp, NULL);
        if (err < 0)
                goto unlink;
  
 -      err = mod_sysfs_setup(mod,
 -                            (struct kernel_param *)
 -                            sechdrs[setupindex].sh_addr,
 -                            sechdrs[setupindex].sh_size
 -                            / sizeof(struct kernel_param));
 +      err = mod_sysfs_setup(mod, kp, num_kp);
        if (err < 0)
                goto unlink;
        add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
@@@ -2430,7 -2475,7 +2432,7 @@@ const char *module_address_lookup(unsig
        const char *ret = NULL;
  
        preempt_disable();
 -      list_for_each_entry(mod, &modules, list) {
 +      list_for_each_entry_rcu(mod, &modules, list) {
                if (within(addr, mod->module_init, mod->init_size)
                    || within(addr, mod->module_core, mod->core_size)) {
                        if (modname)
@@@ -2453,7 -2498,7 +2455,7 @@@ int lookup_module_symbol_name(unsigned 
        struct module *mod;
  
        preempt_disable();
 -      list_for_each_entry(mod, &modules, list) {
 +      list_for_each_entry_rcu(mod, &modules, list) {
                if (within(addr, mod->module_init, mod->init_size) ||
                    within(addr, mod->module_core, mod->core_size)) {
                        const char *sym;
@@@ -2477,7 -2522,7 +2479,7 @@@ int lookup_module_symbol_attrs(unsigne
        struct module *mod;
  
        preempt_disable();
 -      list_for_each_entry(mod, &modules, list) {
 +      list_for_each_entry_rcu(mod, &modules, list) {
                if (within(addr, mod->module_init, mod->init_size) ||
                    within(addr, mod->module_core, mod->core_size)) {
                        const char *sym;
@@@ -2504,7 -2549,7 +2506,7 @@@ int module_get_kallsym(unsigned int sym
        struct module *mod;
  
        preempt_disable();
 -      list_for_each_entry(mod, &modules, list) {
 +      list_for_each_entry_rcu(mod, &modules, list) {
                if (symnum < mod->num_symtab) {
                        *value = mod->symtab[symnum].st_value;
                        *type = mod->symtab[symnum].st_info;
@@@ -2547,7 -2592,7 +2549,7 @@@ unsigned long module_kallsyms_lookup_na
                        ret = mod_find_symname(mod, colon+1);
                *colon = ':';
        } else {
 -              list_for_each_entry(mod, &modules, list)
 +              list_for_each_entry_rcu(mod, &modules, list)
                        if ((ret = mod_find_symname(mod, name)) != 0)
                                break;
        }
  }
  #endif /* CONFIG_KALLSYMS */
  
- /* Called by the /proc file system to return a list of modules. */
- static void *m_start(struct seq_file *m, loff_t *pos)
- {
-       mutex_lock(&module_mutex);
-       return seq_list_start(&modules, *pos);
- }
- static void *m_next(struct seq_file *m, void *p, loff_t *pos)
- {
-       return seq_list_next(p, &modules, pos);
- }
- static void m_stop(struct seq_file *m, void *p)
- {
-       mutex_unlock(&module_mutex);
- }
  static char *module_flags(struct module *mod, char *buf)
  {
        int bx = 0;
        return buf;
  }
  
+ #ifdef CONFIG_PROC_FS
+ /* Called by the /proc file system to return a list of modules. */
+ static void *m_start(struct seq_file *m, loff_t *pos)
+ {
+       mutex_lock(&module_mutex);
+       return seq_list_start(&modules, *pos);
+ }
+ static void *m_next(struct seq_file *m, void *p, loff_t *pos)
+ {
+       return seq_list_next(p, &modules, pos);
+ }
+ static void m_stop(struct seq_file *m, void *p)
+ {
+       mutex_unlock(&module_mutex);
+ }
  static int m_show(struct seq_file *m, void *p)
  {
        struct module *mod = list_entry(p, struct module, list);
     Where refcount is a number or -, and deps is a comma-separated list
     of depends or -.
  */
- const struct seq_operations modules_op = {
static const struct seq_operations modules_op = {
        .start  = m_start,
        .next   = m_next,
        .stop   = m_stop,
        .show   = m_show
  };
  
+ static int modules_open(struct inode *inode, struct file *file)
+ {
+       return seq_open(file, &modules_op);
+ }
+ static const struct file_operations proc_modules_operations = {
+       .open           = modules_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+ };
+ static int __init proc_modules_init(void)
+ {
+       proc_create("modules", 0, NULL, &proc_modules_operations);
+       return 0;
+ }
+ module_init(proc_modules_init);
+ #endif
  /* Given an address, look for it in the module exception tables. */
  const struct exception_table_entry *search_module_extables(unsigned long addr)
  {
        struct module *mod;
  
        preempt_disable();
 -      list_for_each_entry(mod, &modules, list) {
 +      list_for_each_entry_rcu(mod, &modules, list) {
                if (mod->num_exentries == 0)
                        continue;
  
@@@ -2676,7 -2742,7 +2699,7 @@@ int is_module_address(unsigned long add
  
        preempt_disable();
  
 -      list_for_each_entry(mod, &modules, list) {
 +      list_for_each_entry_rcu(mod, &modules, list) {
                if (within(addr, mod->module_core, mod->core_size)) {
                        preempt_enable();
                        return 1;
@@@ -2697,7 -2763,7 +2720,7 @@@ struct module *__module_text_address(un
        if (addr < module_addr_min || addr > module_addr_max)
                return NULL;
  
 -      list_for_each_entry(mod, &modules, list)
 +      list_for_each_entry_rcu(mod, &modules, list)
                if (within(addr, mod->module_init, mod->init_text_size)
                    || within(addr, mod->module_core, mod->core_text_size))
                        return mod;
@@@ -2722,11 -2788,8 +2745,11 @@@ void print_modules(void
        char buf[8];
  
        printk("Modules linked in:");
 -      list_for_each_entry(mod, &modules, list)
 +      /* Most callers should already have preempt disabled, but make sure */
 +      preempt_disable();
 +      list_for_each_entry_rcu(mod, &modules, list)
                printk(" %s%s", mod->name, module_flags(mod, buf));
 +      preempt_enable();
        if (last_unloaded_module[0])
                printk(" [last unloaded: %s]", last_unloaded_module);
        printk("\n");
diff --combined kernel/sched.c
index 1645c7211944b2c6fc23aeea9b890ddf85392289,5a70189d50519b828b1c95c28b5598df342aa556..6625c3c4b10d06c3f76c371becd615d174244902
@@@ -55,6 -55,7 +55,7 @@@
  #include <linux/cpuset.h>
  #include <linux/percpu.h>
  #include <linux/kthread.h>
+ #include <linux/proc_fs.h>
  #include <linux/seq_file.h>
  #include <linux/sysctl.h>
  #include <linux/syscalls.h>
@@@ -227,8 -228,9 +228,8 @@@ static void start_rt_bandwidth(struct r
  
                now = hrtimer_cb_get_time(&rt_b->rt_period_timer);
                hrtimer_forward(&rt_b->rt_period_timer, now, rt_b->rt_period);
 -              hrtimer_start(&rt_b->rt_period_timer,
 -                            rt_b->rt_period_timer.expires,
 -                            HRTIMER_MODE_ABS);
 +              hrtimer_start_expires(&rt_b->rt_period_timer,
 +                              HRTIMER_MODE_ABS);
        }
        spin_unlock(&rt_b->rt_runtime_lock);
  }
@@@ -817,13 -819,6 +818,13 @@@ const_debug unsigned int sysctl_sched_n
   */
  unsigned int sysctl_sched_shares_ratelimit = 250000;
  
 +/*
 + * Inject some fuzzyness into changing the per-cpu group shares
 + * this avoids remote rq-locks at the expense of fairness.
 + * default: 4
 + */
 +unsigned int sysctl_sched_shares_thresh = 4;
 +
  /*
   * period over which we measure -rt task cpu usage in us.
   * default: 1s
@@@ -1070,7 -1065,7 +1071,7 @@@ static void hrtick_start(struct rq *rq
        struct hrtimer *timer = &rq->hrtick_timer;
        ktime_t time = ktime_add_ns(timer->base->get_time(), delay);
  
 -      timer->expires = time;
 +      hrtimer_set_expires(timer, time);
  
        if (rq == this_rq()) {
                hrtimer_restart(timer);
@@@ -1460,8 -1455,8 +1461,8 @@@ static void __set_se_shares(struct sche
   * Calculate and set the cpu's group shares.
   */
  static void
 -__update_group_shares_cpu(struct task_group *tg, int cpu,
 -                        unsigned long sd_shares, unsigned long sd_rq_weight)
 +update_group_shares_cpu(struct task_group *tg, int cpu,
 +                      unsigned long sd_shares, unsigned long sd_rq_weight)
  {
        int boost = 0;
        unsigned long shares;
         *
         */
        shares = (sd_shares * rq_weight) / (sd_rq_weight + 1);
 +      shares = clamp_t(unsigned long, shares, MIN_SHARES, MAX_SHARES);
  
 -      /*
 -       * record the actual number of shares, not the boosted amount.
 -       */
 -      tg->cfs_rq[cpu]->shares = boost ? 0 : shares;
 -      tg->cfs_rq[cpu]->rq_weight = rq_weight;
 +      if (abs(shares - tg->se[cpu]->load.weight) >
 +                      sysctl_sched_shares_thresh) {
 +              struct rq *rq = cpu_rq(cpu);
 +              unsigned long flags;
  
 -      if (shares < MIN_SHARES)
 -              shares = MIN_SHARES;
 -      else if (shares > MAX_SHARES)
 -              shares = MAX_SHARES;
 +              spin_lock_irqsave(&rq->lock, flags);
 +              /*
 +               * record the actual number of shares, not the boosted amount.
 +               */
 +              tg->cfs_rq[cpu]->shares = boost ? 0 : shares;
 +              tg->cfs_rq[cpu]->rq_weight = rq_weight;
  
 -      __set_se_shares(tg->se[cpu], shares);
 +              __set_se_shares(tg->se[cpu], shares);
 +              spin_unlock_irqrestore(&rq->lock, flags);
 +      }
  }
  
  /*
@@@ -1537,8 -1528,14 +1538,8 @@@ static int tg_shares_up(struct task_gro
        if (!rq_weight)
                rq_weight = cpus_weight(sd->span) * NICE_0_LOAD;
  
 -      for_each_cpu_mask(i, sd->span) {
 -              struct rq *rq = cpu_rq(i);
 -              unsigned long flags;
 -
 -              spin_lock_irqsave(&rq->lock, flags);
 -              __update_group_shares_cpu(tg, i, shares, rq_weight);
 -              spin_unlock_irqrestore(&rq->lock, flags);
 -      }
 +      for_each_cpu_mask(i, sd->span)
 +              update_group_shares_cpu(tg, i, shares, rq_weight);
  
        return 0;
  }
@@@ -4447,8 -4444,12 +4448,8 @@@ need_resched_nonpreemptible
        if (sched_feat(HRTICK))
                hrtick_clear(rq);
  
 -      /*
 -       * Do the rq-clock update outside the rq lock:
 -       */
 -      local_irq_disable();
 +      spin_lock_irq(&rq->lock);
        update_rq_clock(rq);
 -      spin_lock(&rq->lock);
        clear_tsk_need_resched(prev);
  
        if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
diff --combined kernel/sched_stats.h
index 2df9d297d292d23fa46db931cdbd0cf9a41af2c0,3d14ce2739023d582aef9bd2f8575eb53b84a1e0..ee71bec1da66a9dcb64d93a0e9934c15a155905b
@@@ -9,7 -9,7 +9,7 @@@
  static int show_schedstat(struct seq_file *seq, void *v)
  {
        int cpu;
 -      int mask_len = NR_CPUS/32 * 9;
 +      int mask_len = DIV_ROUND_UP(NR_CPUS, 32) * 9;
        char *mask_str = kmalloc(mask_len, GFP_KERNEL);
  
        if (mask_str == NULL)
@@@ -90,13 -90,20 +90,20 @@@ static int schedstat_open(struct inode 
        return res;
  }
  
- const struct file_operations proc_schedstat_operations = {
static const struct file_operations proc_schedstat_operations = {
        .open    = schedstat_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
        .release = single_release,
  };
  
+ static int __init proc_schedstat_init(void)
+ {
+       proc_create("schedstat", 0, NULL, &proc_schedstat_operations);
+       return 0;
+ }
+ module_init(proc_schedstat_init);
  /*
   * Expects runqueue lock to be held for atomicity of update
   */