1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2015-2016 Intel Corporation
7 #include <rte_common.h>
8 #include <rte_cycles.h>
11 #include <rte_keepalive.h>
12 #include <rte_malloc.h>
14 struct rte_keepalive
{
18 * Each element must be cache aligned to prevent false sharing.
20 enum rte_keepalive_state core_state __rte_cache_aligned
;
21 } live_data
[RTE_KEEPALIVE_MAXCORES
];
23 /** Last-seen-alive timestamps */
24 uint64_t last_alive
[RTE_KEEPALIVE_MAXCORES
];
28 * Indexed by core id, non-zero if the core should be checked.
30 uint8_t active_cores
[RTE_KEEPALIVE_MAXCORES
];
32 /** Dead core handler. */
33 rte_keepalive_failure_callback_t callback
;
36 * Dead core handler app data.
37 * Pointer is passed to dead core handler.
43 /** Core state relay handler. */
44 rte_keepalive_relay_callback_t relay_callback
;
47 * Core state relay handler app data.
48 * Pointer is passed to live core handler.
50 void *relay_callback_data
;
54 print_trace(const char *msg
, struct rte_keepalive
*keepcfg
, int idx_core
)
56 RTE_LOG(INFO
, EAL
, "%sLast seen %" PRId64
"ms ago.\n",
58 ((rte_rdtsc() - keepcfg
->last_alive
[idx_core
])*1000)
64 rte_keepalive_dispatch_pings(__rte_unused
void *ptr_timer
,
67 struct rte_keepalive
*keepcfg
= ptr_data
;
70 for (idx_core
= 0; idx_core
< RTE_KEEPALIVE_MAXCORES
; idx_core
++) {
71 if (keepcfg
->active_cores
[idx_core
] == 0)
74 switch (keepcfg
->live_data
[idx_core
].core_state
) {
75 case RTE_KA_STATE_UNUSED
:
77 case RTE_KA_STATE_ALIVE
: /* Alive */
78 keepcfg
->live_data
[idx_core
].core_state
=
80 keepcfg
->last_alive
[idx_core
] = rte_rdtsc();
82 case RTE_KA_STATE_MISSING
: /* MIA */
83 print_trace("Core MIA. ", keepcfg
, idx_core
);
84 keepcfg
->live_data
[idx_core
].core_state
=
87 case RTE_KA_STATE_DEAD
: /* Dead */
88 keepcfg
->live_data
[idx_core
].core_state
=
90 print_trace("Core died. ", keepcfg
, idx_core
);
91 if (keepcfg
->callback
)
93 keepcfg
->callback_data
,
97 case RTE_KA_STATE_GONE
: /* Buried */
99 case RTE_KA_STATE_DOZING
: /* Core going idle */
100 keepcfg
->live_data
[idx_core
].core_state
=
102 keepcfg
->last_alive
[idx_core
] = rte_rdtsc();
104 case RTE_KA_STATE_SLEEP
: /* Idled core */
107 if (keepcfg
->relay_callback
)
108 keepcfg
->relay_callback(
109 keepcfg
->relay_callback_data
,
111 keepcfg
->live_data
[idx_core
].core_state
,
112 keepcfg
->last_alive
[idx_core
]
117 struct rte_keepalive
*
118 rte_keepalive_create(rte_keepalive_failure_callback_t callback
,
121 struct rte_keepalive
*keepcfg
;
123 keepcfg
= rte_zmalloc("RTE_EAL_KEEPALIVE",
124 sizeof(struct rte_keepalive
),
125 RTE_CACHE_LINE_SIZE
);
126 if (keepcfg
!= NULL
) {
127 keepcfg
->callback
= callback
;
128 keepcfg
->callback_data
= data
;
129 keepcfg
->tsc_initial
= rte_rdtsc();
130 keepcfg
->tsc_mhz
= rte_get_tsc_hz() / 1000;
135 void rte_keepalive_register_relay_callback(struct rte_keepalive
*keepcfg
,
136 rte_keepalive_relay_callback_t callback
,
139 keepcfg
->relay_callback
= callback
;
140 keepcfg
->relay_callback_data
= data
;
144 rte_keepalive_register_core(struct rte_keepalive
*keepcfg
, const int id_core
)
146 if (id_core
< RTE_KEEPALIVE_MAXCORES
) {
147 keepcfg
->active_cores
[id_core
] = RTE_KA_STATE_ALIVE
;
148 keepcfg
->last_alive
[id_core
] = rte_rdtsc();
153 rte_keepalive_mark_alive(struct rte_keepalive
*keepcfg
)
155 keepcfg
->live_data
[rte_lcore_id()].core_state
= RTE_KA_STATE_ALIVE
;
159 rte_keepalive_mark_sleep(struct rte_keepalive
*keepcfg
)
161 keepcfg
->live_data
[rte_lcore_id()].core_state
= RTE_KA_STATE_DOZING
;