Merge branch 'exec-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm...
[linux-2.6-microblaze.git] / kernel / events / core.c
index 169449b..fcfadec 100644 (file)
@@ -95,11 +95,11 @@ static void remote_function(void *data)
  * @info:      the function call argument
  *
  * Calls the function @func when the task is currently running. This might
- * be on the current CPU, which just calls the function directly
+ * be on the current CPU, which just calls the function directly.  This will
+ * retry due to any failures in smp_call_function_single(), such as if the
+ * task_cpu() goes offline concurrently.
  *
- * returns: @func return value, or
- *         -ESRCH  - when the process isn't running
- *         -EAGAIN - when the process moved away
+ * returns @func return value or -ESRCH when the process isn't running
  */
 static int
 task_function_call(struct task_struct *p, remote_function_f func, void *info)
@@ -112,11 +112,16 @@ task_function_call(struct task_struct *p, remote_function_f func, void *info)
        };
        int ret;
 
-       do {
-               ret = smp_call_function_single(task_cpu(p), remote_function, &data, 1);
-               if (!ret)
-                       ret = data.ret;
-       } while (ret == -EAGAIN);
+       for (;;) {
+               ret = smp_call_function_single(task_cpu(p), remote_function,
+                                              &data, 1);
+               ret = !ret ? data.ret : -EAGAIN;
+
+               if (ret != -EAGAIN)
+                       break;
+
+               cond_resched();
+       }
 
        return ret;
 }
@@ -437,8 +442,7 @@ static void update_perf_cpu_limits(void)
 static bool perf_rotate_context(struct perf_cpu_context *cpuctx);
 
 int perf_proc_update_handler(struct ctl_table *table, int write,
-               void __user *buffer, size_t *lenp,
-               loff_t *ppos)
+               void *buffer, size_t *lenp, loff_t *ppos)
 {
        int ret;
        int perf_cpu = sysctl_perf_cpu_time_max_percent;
@@ -462,8 +466,7 @@ int perf_proc_update_handler(struct ctl_table *table, int write,
 int sysctl_perf_cpu_time_max_percent __read_mostly = DEFAULT_CPU_TIME_MAX_PERCENT;
 
 int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write,
-                               void __user *buffer, size_t *lenp,
-                               loff_t *ppos)
+               void *buffer, size_t *lenp, loff_t *ppos)
 {
        int ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
 
@@ -9404,7 +9407,7 @@ static int perf_kprobe_event_init(struct perf_event *event)
        if (event->attr.type != perf_kprobe.type)
                return -ENOENT;
 
-       if (!capable(CAP_SYS_ADMIN))
+       if (!perfmon_capable())
                return -EACCES;
 
        /*
@@ -9464,7 +9467,7 @@ static int perf_uprobe_event_init(struct perf_event *event)
        if (event->attr.type != perf_uprobe.type)
                return -ENOENT;
 
-       if (!capable(CAP_SYS_ADMIN))
+       if (!perfmon_capable())
                return -EACCES;
 
        /*
@@ -11511,7 +11514,7 @@ SYSCALL_DEFINE5(perf_event_open,
        }
 
        if (attr.namespaces) {
-               if (!capable(CAP_SYS_ADMIN))
+               if (!perfmon_capable())
                        return -EACCES;
        }