1 /* $Id$ */
2 /*
3 ** Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License Version 2 as
7 ** published by the Free Software Foundation.  You may not use, modify or
8 ** distribute this program under any other version of the GNU General
9 ** Public License.
10 **
11 ** This program is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 ** GNU General Public License for more details.
15 **
16 ** You should have received a copy of the GNU General Public License
17 ** along with this program; if not, write to the Free Software
18 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19 */
20 
21 #include "sf_types.h"
22 
23 #include "sfdaq.h"
24 
25 #include "perf_indicators.h"
26 
27 #ifdef PI_PACKET_LATENCY_SUPPORT
28 static PreprocStats *latencyStats = { NULL };
29 #endif
30 
31 static double ticks_per_microsec = 0.0;
32 
getTicksPerMicrosec(void)33 static void getTicksPerMicrosec(void)
34 {
35     if (ticks_per_microsec == 0.0)
36     {
37         ticks_per_microsec = get_ticks_per_usec();
38     }
39 }
40 
41 #ifdef PI_PACKET_LATENCY_SUPPORT
GetPacketLatency(void)42 uint32_t GetPacketLatency(void)
43 {
44     if( (latencyStats != NULL) && (latencyStats->exits != 0) )
45     {
46         getTicksPerMicrosec();
47 
48 	/* The exit counter indicate the number of full enter-exit cycles
49 	 * have been added to the ticks count. */
50         return( (uint32_t)((double)latencyStats->ticks /
51 			   (double)latencyStats->exits /
52 			   ticks_per_microsec));
53     }
54     else
55         return( 0 );
56 }
57 #endif
58 
59 #ifdef PI_PACKET_DROPS_SUPPORT
GetPacketDropPortion(void)60 double GetPacketDropPortion(void)
61 {
62     uint64_t drop, recv, sum;
63     double portion;
64     const DAQ_Stats_t* ps = DAQ_GetStats();
65 
66 /* Debugging code:
67     DAQ_Stats_t test_stats;
68     test_stats.packets_received = 2000;
69     test_stats.hw_packets_dropped = 1050;
70     ps = &test_stats; */
71 
72     recv = ps->packets_received;
73     drop = ps->hw_packets_dropped;
74 
75     sum = recv + drop;
76 
77     if( sum == 0 )
78         portion = 0.0;
79     else
80         portion = ((double)drop / (double)sum);
81 
82     return( portion );
83 }
84 #endif
85 
86 #ifdef PERF_PROFILING
PerfIndicator_RegisterPreprocStat(PreprocStats * Stats,enum Perf_Indicator_Type Type)87 int PerfIndicator_RegisterPreprocStat( PreprocStats *Stats,
88                                        enum Perf_Indicator_Type Type )
89 {
90     if( (Stats != NULL) && (Type == Perf_Indicator_Type_Packet_Latency) )
91     {
92         latencyStats = Stats;
93         return( 0 );
94     }
95     else
96         return( -1 );
97 }
98 #endif
99 
PerfIndicator_GetIndicators(Perf_Indicator_Descriptor_p_t PI_List)100 int PerfIndicator_GetIndicators( Perf_Indicator_Descriptor_p_t PI_List )
101 {
102     if( PI_List == NULL )
103         return( -1 );
104 
105     for( ; PI_List != NULL; PI_List = PI_List->Next )
106     {
107         PI_List->Valid = false;
108         switch( PI_List->Type )
109         {
110 #ifdef PI_PACKET_LATENCY_SUPPORT
111             case( Perf_Indicator_Type_Packet_Latency ):
112             {
113                 PI_List->Indicator.Latency.Latency_us = GetPacketLatency();
114                 PI_List->Valid = true;
115                 break;
116             }
117 #endif
118 #ifdef PI_PROCESSOR_UTILIZATION_SUPPORT
119             case( Perf_Indicator_Type_Processor_Utilization ):
120             {
121                 PI_List->Valid = false;
122                 break;
123             }
124 #endif
125 #ifdef PI_PACKET_DROPS_SUPPORT
126             case( Perf_Indicator_Type_DAQ_Drops ):
127             {
128                 PI_List->Indicator.Drops.Drop_Portion = GetPacketDropPortion();
129                 PI_List->Valid = true;
130                 break;
131             }
132 #endif
133             default:
134             {
135                 return( -1 );
136             }
137         }
138     }
139 
140     return( 0 );
141 }
142