ring-buffer: Have rb_time_cmpxchg() set the msb counter too
[platform/kernel/linux-starfive.git] / kernel / trace / ring_buffer.c
index 0fe35eb..af08a1a 100644 (file)
@@ -706,6 +706,9 @@ static bool rb_time_cmpxchg(rb_time_t *t, u64 expect, u64 set)
        unsigned long cnt2, top2, bottom2, msb2;
        u64 val;
 
+       /* Any interruptions in this function should cause a failure */
+       cnt = local_read(&t->cnt);
+
        /* The cmpxchg always fails if it interrupted an update */
         if (!__rb_time_read(t, &val, &cnt2))
                 return false;
@@ -713,17 +716,18 @@ static bool rb_time_cmpxchg(rb_time_t *t, u64 expect, u64 set)
         if (val != expect)
                 return false;
 
-        cnt = local_read(&t->cnt);
         if ((cnt & 3) != cnt2)
                 return false;
 
         cnt2 = cnt + 1;
 
         rb_time_split(val, &top, &bottom, &msb);
+        msb = rb_time_val_cnt(msb, cnt);
         top = rb_time_val_cnt(top, cnt);
         bottom = rb_time_val_cnt(bottom, cnt);
 
         rb_time_split(set, &top2, &bottom2, &msb2);
+        msb2 = rb_time_val_cnt(msb2, cnt);
         top2 = rb_time_val_cnt(top2, cnt2);
         bottom2 = rb_time_val_cnt(bottom2, cnt2);
 
@@ -3612,14 +3616,14 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
        }
 
        if (likely(tail == w)) {
-               u64 save_before;
-               bool s_ok;
-
                /* Nothing interrupted us between A and C */
  /*D*/         rb_time_set(&cpu_buffer->write_stamp, info->ts);
-               barrier();
- /*E*/         s_ok = rb_time_read(&cpu_buffer->before_stamp, &save_before);
-               RB_WARN_ON(cpu_buffer, !s_ok);
+               /*
+                * If something came in between C and D, the write stamp
+                * may now not be in sync. But that's fine as the before_stamp
+                * will be different and then next event will just be forced
+                * to use an absolute timestamp.
+                */
                if (likely(!(info->add_timestamp &
                             (RB_ADD_STAMP_FORCE | RB_ADD_STAMP_ABSOLUTE))))
                        /* This did not interrupt any time update */
@@ -3627,24 +3631,7 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
                else
                        /* Just use full timestamp for interrupting event */
                        info->delta = info->ts;
-               barrier();
                check_buffer(cpu_buffer, info, tail);
-               if (unlikely(info->ts != save_before)) {
-                       /* SLOW PATH - Interrupted between C and E */
-
-                       a_ok = rb_time_read(&cpu_buffer->write_stamp, &info->after);
-                       RB_WARN_ON(cpu_buffer, !a_ok);
-
-                       /* Write stamp must only go forward */
-                       if (save_before > info->after) {
-                               /*
-                                * We do not care about the result, only that
-                                * it gets updated atomically.
-                                */
-                               (void)rb_time_cmpxchg(&cpu_buffer->write_stamp,
-                                                     info->after, save_before);
-                       }
-               }
        } else {
                u64 ts;
                /* SLOW PATH - Interrupted between A and C */