tree-wide: fix assorted typos all over the place
[safe/jmp/linux-2.6] / arch / ia64 / kernel / perfmon.c
index c8e4037..b3a1cb3 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/capability.h>
 #include <linux/rcupdate.h>
 #include <linux/completion.h>
+#include <linux/tracehook.h>
 
 #include <asm/errno.h>
 #include <asm/intrinsics.h>
@@ -311,7 +312,7 @@ typedef struct pfm_context {
        unsigned long           th_pmcs[PFM_NUM_PMC_REGS];      /* PMC thread save state */
        unsigned long           th_pmds[PFM_NUM_PMD_REGS];      /* PMD thread save state */
 
-       u64                     ctx_saved_psr_up;       /* only contains psr.up value */
+       unsigned long           ctx_saved_psr_up;       /* only contains psr.up value */
 
        unsigned long           ctx_last_activation;    /* context last activation number for last_cpu */
        unsigned int            ctx_last_cpu;           /* CPU id of current or last CPU used (SMP only) */
@@ -867,7 +868,7 @@ pfm_rvfree(void *mem, unsigned long size)
 }
 
 static pfm_context_t *
-pfm_context_alloc(void)
+pfm_context_alloc(int ctx_flags)
 {
        pfm_context_t *ctx;
 
@@ -878,6 +879,46 @@ pfm_context_alloc(void)
        ctx = kzalloc(sizeof(pfm_context_t), GFP_KERNEL);
        if (ctx) {
                DPRINT(("alloc ctx @%p\n", ctx));
+
+               /*
+                * init context protection lock
+                */
+               spin_lock_init(&ctx->ctx_lock);
+
+               /*
+                * context is unloaded
+                */
+               ctx->ctx_state = PFM_CTX_UNLOADED;
+
+               /*
+                * initialization of context's flags
+                */
+               ctx->ctx_fl_block       = (ctx_flags & PFM_FL_NOTIFY_BLOCK) ? 1 : 0;
+               ctx->ctx_fl_system      = (ctx_flags & PFM_FL_SYSTEM_WIDE) ? 1: 0;
+               ctx->ctx_fl_no_msg      = (ctx_flags & PFM_FL_OVFL_NO_MSG) ? 1: 0;
+               /*
+                * will move to set properties
+                * ctx->ctx_fl_excl_idle   = (ctx_flags & PFM_FL_EXCL_IDLE) ? 1: 0;
+                */
+
+               /*
+                * init restart semaphore to locked
+                */
+               init_completion(&ctx->ctx_restart_done);
+
+               /*
+                * activation is used in SMP only
+                */
+               ctx->ctx_last_activation = PFM_INVALID_ACTIVATION;
+               SET_LAST_CPU(ctx, -1);
+
+               /*
+                * initialize notification message queue
+                */
+               ctx->ctx_msgq_head = ctx->ctx_msgq_tail = 0;
+               init_waitqueue_head(&ctx->ctx_msgq_wait);
+               init_waitqueue_head(&ctx->ctx_zombieq);
+
        }
        return ctx;
 }
@@ -1780,7 +1821,7 @@ pfm_syswide_cleanup_other_cpu(pfm_context_t *ctx)
        int ret;
 
        DPRINT(("calling CPU%d for cleanup\n", ctx->ctx_cpu));
-       ret = smp_call_function_single(ctx->ctx_cpu, pfm_syswide_force_stop, ctx, 0, 1);
+       ret = smp_call_function_single(ctx->ctx_cpu, pfm_syswide_force_stop, ctx, 1);
        DPRINT(("called CPU%d for cleanup ret=%d\n", ctx->ctx_cpu, ret));
 }
 #endif /* CONFIG_SMP */
@@ -1824,11 +1865,6 @@ pfm_flush(struct file *filp, fl_owner_t id)
         * invoked after, it will find an empty queue and no
         * signal will be sent. In both case, we are safe
         */
-       if (filp->f_flags & FASYNC) {
-               DPRINT(("cleaning up async_queue=%p\n", ctx->ctx_async_queue));
-               pfm_do_fasync (-1, filp, ctx, 0);
-       }
-
        PROTECT_CTX(ctx, flags);
 
        state     = ctx->ctx_state;
@@ -2160,98 +2196,60 @@ pfmfs_delete_dentry(struct dentry *dentry)
        return 1;
 }
 
-static struct dentry_operations pfmfs_dentry_operations = {
+static const struct dentry_operations pfmfs_dentry_operations = {
        .d_delete = pfmfs_delete_dentry,
 };
 
 
-static int
-pfm_alloc_fd(struct file **cfile)
+static struct file *
+pfm_alloc_file(pfm_context_t *ctx)
 {
-       int fd, ret = 0;
-       struct file *file = NULL;
-       struct inode * inode;
+       struct file *file;
+       struct inode *inode;
+       struct dentry *dentry;
        char name[32];
        struct qstr this;
 
-       fd = get_unused_fd();
-       if (fd < 0) return -ENFILE;
-
-       ret = -ENFILE;
-
-       file = get_empty_filp();
-       if (!file) goto out;
-
        /*
         * allocate a new inode
         */
        inode = new_inode(pfmfs_mnt->mnt_sb);
-       if (!inode) goto out;
+       if (!inode)
+               return ERR_PTR(-ENOMEM);
 
        DPRINT(("new inode ino=%ld @%p\n", inode->i_ino, inode));
 
        inode->i_mode = S_IFCHR|S_IRUGO;
-       inode->i_uid  = current->fsuid;
-       inode->i_gid  = current->fsgid;
+       inode->i_uid  = current_fsuid();
+       inode->i_gid  = current_fsgid();
 
        sprintf(name, "[%lu]", inode->i_ino);
        this.name = name;
        this.len  = strlen(name);
        this.hash = inode->i_ino;
 
-       ret = -ENOMEM;
-
        /*
         * allocate a new dcache entry
         */
-       file->f_path.dentry = d_alloc(pfmfs_mnt->mnt_sb->s_root, &this);
-       if (!file->f_path.dentry) goto out;
+       dentry = d_alloc(pfmfs_mnt->mnt_sb->s_root, &this);
+       if (!dentry) {
+               iput(inode);
+               return ERR_PTR(-ENOMEM);
+       }
 
-       file->f_path.dentry->d_op = &pfmfs_dentry_operations;
+       dentry->d_op = &pfmfs_dentry_operations;
+       d_add(dentry, inode);
 
-       d_add(file->f_path.dentry, inode);
-       file->f_path.mnt = mntget(pfmfs_mnt);
-       file->f_mapping = inode->i_mapping;
+       file = alloc_file(pfmfs_mnt, dentry, FMODE_READ, &pfm_file_ops);
+       if (!file) {
+               dput(dentry);
+               return ERR_PTR(-ENFILE);
+       }
 
-       file->f_op    = &pfm_file_ops;
-       file->f_mode  = FMODE_READ;
        file->f_flags = O_RDONLY;
-       file->f_pos   = 0;
-
-       /*
-        * may have to delay until context is attached?
-        */
-       fd_install(fd, file);
-
-       /*
-        * the file structure we will use
-        */
-       *cfile = file;
+       file->private_data = ctx;
 
-       return fd;
-out:
-       if (file) put_filp(file);
-       put_unused_fd(fd);
-       return ret;
-}
-
-static void
-pfm_free_fd(int fd, struct file *file)
-{
-       struct files_struct *files = current->files;
-       struct fdtable *fdt;
-
-       /* 
-        * there ie no fd_uninstall(), so we do it here
-        */
-       spin_lock(&files->file_lock);
-       fdt = files_fdtable(files);
-       rcu_assign_pointer(fdt->fd[fd], NULL);
-       spin_unlock(&files->file_lock);
-
-       if (file)
-               put_filp(file);
-       put_unused_fd(fd);
+       return file;
 }
 
 static int
@@ -2401,22 +2399,33 @@ error_kmem:
 static int
 pfm_bad_permissions(struct task_struct *task)
 {
+       const struct cred *tcred;
+       uid_t uid = current_uid();
+       gid_t gid = current_gid();
+       int ret;
+
+       rcu_read_lock();
+       tcred = __task_cred(task);
+
        /* inspired by ptrace_attach() */
        DPRINT(("cur: uid=%d gid=%d task: euid=%d suid=%d uid=%d egid=%d sgid=%d\n",
-               current->uid,
-               current->gid,
-               task->euid,
-               task->suid,
-               task->uid,
-               task->egid,
-               task->sgid));
-
-       return ((current->uid != task->euid)
-           || (current->uid != task->suid)
-           || (current->uid != task->uid)
-           || (current->gid != task->egid)
-           || (current->gid != task->sgid)
-           || (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE);
+               uid,
+               gid,
+               tcred->euid,
+               tcred->suid,
+               tcred->uid,
+               tcred->egid,
+               tcred->sgid));
+
+       ret = ((uid != tcred->euid)
+              || (uid != tcred->suid)
+              || (uid != tcred->uid)
+              || (gid != tcred->egid)
+              || (gid != tcred->sgid)
+              || (gid != tcred->gid)) && !capable(CAP_SYS_PTRACE);
+
+       rcu_read_unlock();
+       return ret;
 }
 
 static int
@@ -2475,6 +2484,7 @@ pfm_setup_buffer_fmt(struct task_struct *task, struct file *filp, pfm_context_t
 
        /* link buffer format and context */
        ctx->ctx_buf_fmt = fmt;
+       ctx->ctx_fl_is_sampling = 1; /* assume record() is defined */
 
        /*
         * check if buffer format wants to use perfmon buffer allocation/mapping service
@@ -2623,7 +2633,7 @@ pfm_task_incompatible(pfm_context_t *ctx, struct task_struct *task)
        /*
         * make sure the task is off any CPU
         */
-       wait_task_inactive(task);
+       wait_task_inactive(task, 0);
 
        /* more to come... */
 
@@ -2669,78 +2679,45 @@ pfm_context_create(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg
 {
        pfarg_context_t *req = (pfarg_context_t *)arg;
        struct file *filp;
+       struct path path;
        int ctx_flags;
+       int fd;
        int ret;
 
        /* let's check the arguments first */
        ret = pfarg_is_sane(current, req);
-       if (ret < 0) return ret;
+       if (ret < 0)
+               return ret;
 
        ctx_flags = req->ctx_flags;
 
        ret = -ENOMEM;
 
-       ctx = pfm_context_alloc();
-       if (!ctx) goto error;
+       fd = get_unused_fd();
+       if (fd < 0)
+               return fd;
 
-       ret = pfm_alloc_fd(&filp);
-       if (ret < 0) goto error_file;
+       ctx = pfm_context_alloc(ctx_flags);
+       if (!ctx)
+               goto error;
 
-       req->ctx_fd = ctx->ctx_fd = ret;
+       filp = pfm_alloc_file(ctx);
+       if (IS_ERR(filp)) {
+               ret = PTR_ERR(filp);
+               goto error_file;
+       }
 
-       /*
-        * attach context to file
-        */
-       filp->private_data = ctx;
+       req->ctx_fd = ctx->ctx_fd = fd;
 
        /*
         * does the user want to sample?
         */
        if (pfm_uuid_cmp(req->ctx_smpl_buf_id, pfm_null_uuid)) {
                ret = pfm_setup_buffer_fmt(current, filp, ctx, ctx_flags, 0, req);
-               if (ret) goto buffer_error;
+               if (ret)
+                       goto buffer_error;
        }
 
-       /*
-        * init context protection lock
-        */
-       spin_lock_init(&ctx->ctx_lock);
-
-       /*
-        * context is unloaded
-        */
-       ctx->ctx_state = PFM_CTX_UNLOADED;
-
-       /*
-        * initialization of context's flags
-        */
-       ctx->ctx_fl_block       = (ctx_flags & PFM_FL_NOTIFY_BLOCK) ? 1 : 0;
-       ctx->ctx_fl_system      = (ctx_flags & PFM_FL_SYSTEM_WIDE) ? 1: 0;
-       ctx->ctx_fl_is_sampling = ctx->ctx_buf_fmt ? 1 : 0; /* assume record() is defined */
-       ctx->ctx_fl_no_msg      = (ctx_flags & PFM_FL_OVFL_NO_MSG) ? 1: 0;
-       /*
-        * will move to set properties
-        * ctx->ctx_fl_excl_idle   = (ctx_flags & PFM_FL_EXCL_IDLE) ? 1: 0;
-        */
-
-       /*
-        * init restart semaphore to locked
-        */
-       init_completion(&ctx->ctx_restart_done);
-
-       /*
-        * activation is used in SMP only
-        */
-       ctx->ctx_last_activation = PFM_INVALID_ACTIVATION;
-       SET_LAST_CPU(ctx, -1);
-
-       /*
-        * initialize notification message queue
-        */
-       ctx->ctx_msgq_head = ctx->ctx_msgq_tail = 0;
-       init_waitqueue_head(&ctx->ctx_msgq_wait);
-       init_waitqueue_head(&ctx->ctx_zombieq);
-
        DPRINT(("ctx=%p flags=0x%x system=%d notify_block=%d excl_idle=%d no_msg=%d ctx_fd=%d \n",
                ctx,
                ctx_flags,
@@ -2755,10 +2732,14 @@ pfm_context_create(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg
         */
        pfm_reset_pmu_state(ctx);
 
+       fd_install(fd, filp);
+
        return 0;
 
 buffer_error:
-       pfm_free_fd(ctx->ctx_fd, filp);
+       path = filp->f_path;
+       put_filp(filp);
+       path_put(&path);
 
        if (ctx->ctx_buf_fmt) {
                pfm_buf_fmt_exit(ctx->ctx_buf_fmt, current, NULL, regs);
@@ -2767,6 +2748,7 @@ error_file:
        pfm_context_free(ctx);
 
 error:
+       put_unused_fd(fd);
        return ret;
 }
 
@@ -3541,7 +3523,7 @@ pfm_use_debug_registers(struct task_struct *task)
  * IA64_THREAD_DBG_VALID set. This indicates a task which was
  * able to use the debug registers for debugging purposes via
  * ptrace(). Therefore we know it was not using them for
- * perfmormance monitoring, so we only decrement the number
+ * performance monitoring, so we only decrement the number
  * of "ptraced" debug register users to keep the count up to date
  */
 int
@@ -3709,7 +3691,7 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 
                PFM_SET_WORK_PENDING(task, 1);
 
-               tsk_set_notify_resume(task);
+               set_notify_resume(task);
 
                /*
                 * XXX: send reschedule if task runs on another CPU
@@ -4799,7 +4781,7 @@ recheck:
 
                UNPROTECT_CTX(ctx, flags);
 
-               wait_task_inactive(task);
+               wait_task_inactive(task, 0);
 
                PROTECT_CTX(ctx, flags);
 
@@ -5038,12 +5020,13 @@ pfm_context_force_terminate(pfm_context_t *ctx, struct pt_regs *regs)
 }
 
 static int pfm_ovfl_notify_user(pfm_context_t *ctx, unsigned long ovfl_pmds);
+
  /*
   * pfm_handle_work() can be called with interrupts enabled
   * (TIF_NEED_RESCHED) or disabled. The down_interruptible
   * call may sleep, therefore we must re-enable interrupts
   * to avoid deadlocks. It is safe to do so because this function
-  * is called ONLY when returning to user level (PUStk=1), in which case
+  * is called ONLY when returning to user level (pUStk=1), in which case
   * there is no risk of kernel stack overflow due to deep
   * interrupt nesting.
   */
@@ -5059,7 +5042,8 @@ pfm_handle_work(void)
 
        ctx = PFM_GET_CTX(current);
        if (ctx == NULL) {
-               printk(KERN_ERR "perfmon: [%d] has no PFM context\n", task_pid_nr(current));
+               printk(KERN_ERR "perfmon: [%d] has no PFM context\n",
+                       task_pid_nr(current));
                return;
        }
 
@@ -5067,8 +5051,6 @@ pfm_handle_work(void)
 
        PFM_SET_WORK_PENDING(current, 0);
 
-       tsk_clear_notify_resume(current);
-
        regs = task_pt_regs(current);
 
        /*
@@ -5083,11 +5065,12 @@ pfm_handle_work(void)
        /*
         * must be done before we check for simple-reset mode
         */
-       if (ctx->ctx_fl_going_zombie || ctx->ctx_state == PFM_CTX_ZOMBIE) goto do_zombie;
-
+       if (ctx->ctx_fl_going_zombie || ctx->ctx_state == PFM_CTX_ZOMBIE)
+               goto do_zombie;
 
        //if (CTX_OVFL_NOBLOCK(ctx)) goto skip_blocking;
-       if (reason == PFM_TRAP_REASON_RESET) goto skip_blocking;
+       if (reason == PFM_TRAP_REASON_RESET)
+               goto skip_blocking;
 
        /*
         * restore interrupt mask to what it was on entry.
@@ -5135,7 +5118,8 @@ do_zombie:
        /*
         * in case of interruption of down() we don't restart anything
         */
-       if (ret < 0) goto nothing_to_do;
+       if (ret < 0)
+               goto nothing_to_do;
 
 skip_blocking:
        pfm_resume_after_ovfl(ctx, ovfl_regs, regs);
@@ -5229,8 +5213,8 @@ pfm_end_notify_user(pfm_context_t *ctx)
  * main overflow processing routine.
  * it can be called from the interrupt path or explicitly during the context switch code
  */
-static void
-pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, struct pt_regs *regs)
+static void pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx,
+                               unsigned long pmc0, struct pt_regs *regs)
 {
        pfm_ovfl_arg_t *ovfl_arg;
        unsigned long mask;
@@ -5435,7 +5419,7 @@ pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, str
                         * when coming from ctxsw, current still points to the
                         * previous task, therefore we must work with task and not current.
                         */
-                       tsk_set_notify_resume(task);
+                       set_notify_resume(task);
                }
                /*
                 * defer until state is changed (shorten spin window). the context is locked
@@ -5611,7 +5595,7 @@ pfm_interrupt_handler(int irq, void *arg)
                (*pfm_alt_intr_handler->handler)(irq, arg, regs);
        }
 
-       put_cpu_no_resched();
+       put_cpu();
        return IRQ_HANDLED;
 }
 
@@ -5619,7 +5603,7 @@ pfm_interrupt_handler(int irq, void *arg)
  * /proc/perfmon interface, for debug only
  */
 
-#define PFM_PROC_SHOW_HEADER   ((void *)NR_CPUS+1)
+#define PFM_PROC_SHOW_HEADER   ((void *)(long)nr_cpu_ids+1)
 
 static void *
 pfm_proc_start(struct seq_file *m, loff_t *pos)
@@ -5628,7 +5612,7 @@ pfm_proc_start(struct seq_file *m, loff_t *pos)
                return PFM_PROC_SHOW_HEADER;
        }
 
-       while (*pos <= NR_CPUS) {
+       while (*pos <= nr_cpu_ids) {
                if (cpu_online(*pos - 1)) {
                        return (void *)*pos;
                }
@@ -6529,7 +6513,7 @@ pfm_install_alt_pmu_interrupt(pfm_intr_handler_desc_t *hdl)
        }
 
        /* save the current system wide pmu states */
-       ret = on_each_cpu(pfm_alt_save_pmu_state, NULL, 0, 1);
+       ret = on_each_cpu(pfm_alt_save_pmu_state, NULL, 1);
        if (ret) {
                DPRINT(("on_each_cpu() failed: %d\n", ret));
                goto cleanup_reserve;
@@ -6574,7 +6558,7 @@ pfm_remove_alt_pmu_interrupt(pfm_intr_handler_desc_t *hdl)
 
        pfm_alt_intr_handler = NULL;
 
-       ret = on_each_cpu(pfm_alt_restore_pmu_state, NULL, 0, 1);
+       ret = on_each_cpu(pfm_alt_restore_pmu_state, NULL, 1);
        if (ret) {
                DPRINT(("on_each_cpu() failed: %d\n", ret));
        }
@@ -6695,16 +6679,12 @@ pfm_init(void)
        /*
         * create /proc/perfmon (mostly for debugging purposes)
         */
-       perfmon_dir = create_proc_entry("perfmon", S_IRUGO, NULL);
+       perfmon_dir = proc_create("perfmon", S_IRUGO, NULL, &pfm_proc_fops);
        if (perfmon_dir == NULL) {
                printk(KERN_ERR "perfmon: cannot create /proc entry, perfmon disabled\n");
                pmu_conf = NULL;
                return -1;
        }
-       /*
-        * install customized file operations for /proc/perfmon entry
-        */
-       perfmon_dir->proc_fops = &pfm_proc_fops;
 
        /*
         * create /proc/sys/kernel/perfmon (for debugging purposes)