LCOV - code coverage report
Current view: top level - external/trace - trace.c (source / functions) Coverage Total Hit
Test: skiboot.info Lines: 100.0 % 39 39
Test Date: 2025-01-24 18:40:10 Functions: 100.0 % 2 2
Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : // SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
       2                 :             : /*
       3                 :             :  * This example code shows how to read from the trace buffer.
       4                 :             :  *
       5                 :             :  * Copyright 2013-2019 IBM Corp.
       6                 :             :  */
       7                 :             : 
       8                 :             : #include <external/trace/trace.h>
       9                 :             : #include "../ccan/endian/endian.h"
      10                 :             : #include "../ccan/short_types/short_types.h"
      11                 :             : #include "trace.h"
      12                 :             : #include <trace_types.h>
      13                 :             : #include <errno.h>
      14                 :             : 
      15                 :             : #if defined(__powerpc__) || defined(__powerpc64__)
      16                 :             : #define rmb() lwsync()
      17                 :             : #else
      18                 :             : #define rmb()
      19                 :             : #endif
      20                 :             : 
      21                 :     3995508 : bool trace_empty(const struct trace_reader *tr)
      22                 :             : {
      23                 :             :         const struct trace_repeat *rep;
      24                 :             : 
      25                 :     3995508 :         if (tr->rpos == be64_to_cpu(tr->tb->end))
      26                 :          42 :                 return true;
      27                 :             : 
      28                 :             :         /*
      29                 :             :          * If we have a single element only, and it's a repeat buffer
      30                 :             :          * we've already seen every repeat for (yet which may be
      31                 :             :          * incremented in future), we're also empty.
      32                 :             :          */
      33                 :     3995466 :         rep = (void *)tr->tb->buf + tr->rpos % be64_to_cpu(tr->tb->buf_size);
      34                 :     3995466 :         if (be64_to_cpu(tr->tb->end) != tr->rpos + sizeof(*rep))
      35                 :     1902598 :                 return false;
      36                 :             : 
      37                 :     2092868 :         if (rep->type != TRACE_REPEAT)
      38                 :          13 :                 return false;
      39                 :             : 
      40                 :     2092855 :         if (be16_to_cpu(rep->num) != tr->last_repeat)
      41                 :     1046434 :                 return false;
      42                 :             : 
      43                 :     1046421 :         return true;
      44                 :             : }
      45                 :             : 
      46                 :             : /* You can't read in parallel, so some locking required in caller. */
      47                 :     3995504 : bool trace_get(union trace *t, struct trace_reader *tr)
      48                 :             : {
      49                 :             :         u64 start, rpos;
      50                 :             :         size_t len;
      51                 :             : 
      52                 :     7991008 :         len = sizeof(*t) < be32_to_cpu(tr->tb->max_size) ? sizeof(*t) :
      53                 :     3995504 :                 be32_to_cpu(tr->tb->max_size);
      54                 :             : 
      55                 :     3995504 :         if (trace_empty(tr))
      56                 :     1046459 :                 return false;
      57                 :             : 
      58                 :     2949045 : again:
      59                 :             :         /*
      60                 :             :          * The actual buffer is slightly larger than tbsize, so this
      61                 :             :          * memcpy is always valid.
      62                 :             :          */
      63                 :     3668529 :         memcpy(t, tr->tb->buf + tr->rpos % be64_to_cpu(tr->tb->buf_size), len);
      64                 :             : 
      65                 :             :         rmb(); /* read barrier, so we read tr->tb->start after copying record. */
      66                 :             : 
      67                 :     3668529 :         start = be64_to_cpu(tr->tb->start);
      68                 :     3668529 :         rpos = tr->rpos;
      69                 :             : 
      70                 :             :         /* Now, was that overwritten? */
      71                 :     3668529 :         if (rpos < start) {
      72                 :             :                 /* Create overflow record. */
      73                 :          35 :                 t->overflow.unused64 = 0;
      74                 :          35 :                 t->overflow.type = TRACE_OVERFLOW;
      75                 :          35 :                 t->overflow.len_div_8 = sizeof(t->overflow) / 8;
      76                 :          35 :                 t->overflow.bytes_missed = cpu_to_be64(start - rpos);
      77                 :          35 :                 tr->rpos = start;
      78                 :          35 :                 return true;
      79                 :             :         }
      80                 :             : 
      81                 :             :         /* Repeat entries need special handling */
      82                 :     3668494 :         if (t->hdr.type == TRACE_REPEAT) {
      83                 :     2485383 :                 u32 num = be16_to_cpu(t->repeat.num);
      84                 :             : 
      85                 :             :                 /* In case we've read some already... */
      86                 :     2485383 :                 t->repeat.num = cpu_to_be16(num - tr->last_repeat);
      87                 :             : 
      88                 :             :                 /* Record how many repeats we saw this time. */
      89                 :     2485383 :                 tr->last_repeat = num;
      90                 :             : 
      91                 :             :                 /* Don't report an empty repeat buffer. */
      92                 :     2485383 :                 if (t->repeat.num == 0) {
      93                 :             :                         /*
      94                 :             :                          * This can't be the last buffer, otherwise
      95                 :             :                          * trace_empty would have returned true.
      96                 :             :                          */
      97                 :      719484 :                         assert(be64_to_cpu(tr->tb->end) >
      98                 :             :                                rpos + t->hdr.len_div_8 * 8);
      99                 :             :                         /* Skip to next entry. */
     100                 :      719484 :                         tr->rpos = rpos + t->hdr.len_div_8 * 8;
     101                 :      719484 :                         tr->last_repeat = 0;
     102                 :      719484 :                         goto again;
     103                 :             :                 }
     104                 :             :         } else {
     105                 :     1183111 :                 tr->last_repeat = 0;
     106                 :     1183111 :                 tr->rpos = rpos + t->hdr.len_div_8 * 8;
     107                 :             :         }
     108                 :             : 
     109                 :     2949010 :         return true;
     110                 :             : }
        

Generated by: LCOV version 2.0-1