LCOV - code coverage report
Current view: top level - external/trace - trace.c (source / functions) Hit Total Coverage
Test: skiboot.info Lines: 39 39 100.0 %
Date: 2024-09-10 18:37:41 Functions: 2 2 100.0 %
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                 :    4379461 : bool trace_empty(const struct trace_reader *tr)
      22                 :            : {
      23                 :            :         const struct trace_repeat *rep;
      24                 :            : 
      25                 :    4379461 :         if (tr->rpos == be64_to_cpu(tr->tb->end))
      26                 :     120523 :                 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                 :    4258938 :         rep = (void *)tr->tb->buf + tr->rpos % be64_to_cpu(tr->tb->buf_size);
      34                 :    4258938 :         if (be64_to_cpu(tr->tb->end) != tr->rpos + sizeof(*rep))
      35                 :    2078770 :                 return false;
      36                 :            : 
      37                 :    2180168 :         if (rep->type != TRACE_REPEAT)
      38                 :         16 :                 return false;
      39                 :            : 
      40                 :    2180152 :         if (be16_to_cpu(rep->num) != tr->last_repeat)
      41                 :    1105555 :                 return false;
      42                 :            : 
      43                 :    1074597 :         return true;
      44                 :            : }
      45                 :            : 
      46                 :            : /* You can't read in parallel, so some locking required in caller. */
      47                 :    4379457 : bool trace_get(union trace *t, struct trace_reader *tr)
      48                 :            : {
      49                 :            :         u64 start, rpos;
      50                 :            :         size_t len;
      51                 :            : 
      52                 :    8758914 :         len = sizeof(*t) < be32_to_cpu(tr->tb->max_size) ? sizeof(*t) :
      53                 :    4379457 :                 be32_to_cpu(tr->tb->max_size);
      54                 :            : 
      55                 :    4379457 :         if (trace_empty(tr))
      56                 :    1195116 :                 return false;
      57                 :            : 
      58                 :    3184341 : again:
      59                 :            :         /*
      60                 :            :          * The actual buffer is slightly larger than tbsize, so this
      61                 :            :          * memcpy is always valid.
      62                 :            :          */
      63                 :    3988437 :         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                 :    3988437 :         start = be64_to_cpu(tr->tb->start);
      68                 :    3988437 :         rpos = tr->rpos;
      69                 :            : 
      70                 :            :         /* Now, was that overwritten? */
      71                 :    3988437 :         if (rpos < start) {
      72                 :            :                 /* Create overflow record. */
      73                 :         31 :                 t->overflow.unused64 = 0;
      74                 :         31 :                 t->overflow.type = TRACE_OVERFLOW;
      75                 :         31 :                 t->overflow.len_div_8 = sizeof(t->overflow) / 8;
      76                 :         31 :                 t->overflow.bytes_missed = cpu_to_be64(start - rpos);
      77                 :         31 :                 tr->rpos = start;
      78                 :         31 :                 return true;
      79                 :            :         }
      80                 :            : 
      81                 :            :         /* Repeat entries need special handling */
      82                 :    3988406 :         if (t->hdr.type == TRACE_REPEAT) {
      83                 :    2689472 :                 u32 num = be16_to_cpu(t->repeat.num);
      84                 :            : 
      85                 :            :                 /* In case we've read some already... */
      86                 :    2689472 :                 t->repeat.num = cpu_to_be16(num - tr->last_repeat);
      87                 :            : 
      88                 :            :                 /* Record how many repeats we saw this time. */
      89                 :    2689472 :                 tr->last_repeat = num;
      90                 :            : 
      91                 :            :                 /* Don't report an empty repeat buffer. */
      92                 :    2689472 :                 if (t->repeat.num == 0) {
      93                 :            :                         /*
      94                 :            :                          * This can't be the last buffer, otherwise
      95                 :            :                          * trace_empty would have returned true.
      96                 :            :                          */
      97                 :     804096 :                         assert(be64_to_cpu(tr->tb->end) >
      98                 :            :                                rpos + t->hdr.len_div_8 * 8);
      99                 :            :                         /* Skip to next entry. */
     100                 :     804096 :                         tr->rpos = rpos + t->hdr.len_div_8 * 8;
     101                 :     804096 :                         tr->last_repeat = 0;
     102                 :     804096 :                         goto again;
     103                 :            :                 }
     104                 :            :         } else {
     105                 :    1298934 :                 tr->last_repeat = 0;
     106                 :    1298934 :                 tr->rpos = rpos + t->hdr.len_div_8 * 8;
     107                 :            :         }
     108                 :            : 
     109                 :    3184310 :         return true;
     110                 :            : }

Generated by: LCOV version 1.14