drm: add a locked version of drm_is_current_master
[linux-2.6-microblaze.git] / kernel / bpf / helpers.c
index 5447739..7344349 100644 (file)
@@ -692,38 +692,41 @@ static int bpf_trace_copy_string(char *buf, void *unsafe_ptr, char fmt_ptype,
        return -EINVAL;
 }
 
-/* Per-cpu temp buffers which can be used by printf-like helpers for %s or %p
+/* Per-cpu temp buffers used by printf-like helpers to store the bprintf binary
+ * arguments representation.
  */
-#define MAX_PRINTF_BUF_LEN     512
+#define MAX_BPRINTF_BUF_LEN    512
 
-struct bpf_printf_buf {
-       char tmp_buf[MAX_PRINTF_BUF_LEN];
+/* Support executing three nested bprintf helper calls on a given CPU */
+#define MAX_BPRINTF_NEST_LEVEL 3
+struct bpf_bprintf_buffers {
+       char tmp_bufs[MAX_BPRINTF_NEST_LEVEL][MAX_BPRINTF_BUF_LEN];
 };
-static DEFINE_PER_CPU(struct bpf_printf_buf, bpf_printf_buf);
-static DEFINE_PER_CPU(int, bpf_printf_buf_used);
+static DEFINE_PER_CPU(struct bpf_bprintf_buffers, bpf_bprintf_bufs);
+static DEFINE_PER_CPU(int, bpf_bprintf_nest_level);
 
 static int try_get_fmt_tmp_buf(char **tmp_buf)
 {
-       struct bpf_printf_buf *bufs;
-       int used;
+       struct bpf_bprintf_buffers *bufs;
+       int nest_level;
 
        preempt_disable();
-       used = this_cpu_inc_return(bpf_printf_buf_used);
-       if (WARN_ON_ONCE(used > 1)) {
-               this_cpu_dec(bpf_printf_buf_used);
+       nest_level = this_cpu_inc_return(bpf_bprintf_nest_level);
+       if (WARN_ON_ONCE(nest_level > MAX_BPRINTF_NEST_LEVEL)) {
+               this_cpu_dec(bpf_bprintf_nest_level);
                preempt_enable();
                return -EBUSY;
        }
-       bufs = this_cpu_ptr(&bpf_printf_buf);
-       *tmp_buf = bufs->tmp_buf;
+       bufs = this_cpu_ptr(&bpf_bprintf_bufs);
+       *tmp_buf = bufs->tmp_bufs[nest_level - 1];
 
        return 0;
 }
 
 void bpf_bprintf_cleanup(void)
 {
-       if (this_cpu_read(bpf_printf_buf_used)) {
-               this_cpu_dec(bpf_printf_buf_used);
+       if (this_cpu_read(bpf_bprintf_nest_level)) {
+               this_cpu_dec(bpf_bprintf_nest_level);
                preempt_enable();
        }
 }
@@ -760,7 +763,7 @@ int bpf_bprintf_prepare(char *fmt, u32 fmt_size, const u64 *raw_args,
                if (num_args && try_get_fmt_tmp_buf(&tmp_buf))
                        return -EBUSY;
 
-               tmp_buf_end = tmp_buf + MAX_PRINTF_BUF_LEN;
+               tmp_buf_end = tmp_buf + MAX_BPRINTF_BUF_LEN;
                *bin_args = (u32 *)tmp_buf;
        }