xref: /f-stack/dpdk/examples/l2fwd-keepalive/shm.c (revision d30ea906)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2016 Intel Corporation
3  */
4 
5 #include <time.h>
6 
7 #include <rte_common.h>
8 #include <rte_log.h>
9 #include <rte_keepalive.h>
10 
11 #include "shm.h"
12 
rte_keepalive_shm_create(void)13 struct rte_keepalive_shm *rte_keepalive_shm_create(void)
14 {
15 	int fd;
16 	int idx_core;
17 	struct rte_keepalive_shm *ka_shm;
18 
19 	/* If any existing object is not unlinked, it makes it all too easy
20 	 * for clients to end up with stale shared memory blocks when
21 	 * restarted. Unlinking makes sure subsequent shm_open by clients
22 	 * will get the new block mapped below.
23 	 */
24 	if (shm_unlink(RTE_KEEPALIVE_SHM_NAME) == -1 && errno != ENOENT)
25 		printf("Warning: Error unlinking stale %s (%s)\n",
26 			RTE_KEEPALIVE_SHM_NAME, strerror(errno));
27 
28 	fd = shm_open(RTE_KEEPALIVE_SHM_NAME,
29 		O_CREAT | O_TRUNC | O_RDWR, 0666);
30 	if (fd < 0)
31 		RTE_LOG(INFO, EAL,
32 			"Failed to open %s as SHM (%s)\n",
33 			RTE_KEEPALIVE_SHM_NAME,
34 			strerror(errno));
35 	else if (ftruncate(fd, sizeof(struct rte_keepalive_shm)) != 0)
36 		RTE_LOG(INFO, EAL,
37 			"Failed to resize SHM (%s)\n", strerror(errno));
38 	else {
39 		ka_shm = (struct rte_keepalive_shm *) mmap(
40 			0, sizeof(struct rte_keepalive_shm),
41 			PROT_READ | PROT_WRITE,	MAP_SHARED, fd, 0);
42 		close(fd);
43 		if (ka_shm == MAP_FAILED)
44 			RTE_LOG(INFO, EAL,
45 				"Failed to mmap SHM (%s)\n", strerror(errno));
46 		else {
47 			memset(ka_shm, 0, sizeof(struct rte_keepalive_shm));
48 
49 			/* Initialize the semaphores for IPC/SHM use */
50 			if (sem_init(&ka_shm->core_died, 1, 0) != 0) {
51 				RTE_LOG(INFO, EAL,
52 					"Failed to setup SHM semaphore (%s)\n",
53 					strerror(errno));
54 				munmap(ka_shm,
55 					sizeof(struct rte_keepalive_shm));
56 				return NULL;
57 			}
58 
59 			/* Set all cores to 'not present' */
60 			for (idx_core = 0;
61 					idx_core < RTE_KEEPALIVE_MAXCORES;
62 					idx_core++) {
63 				ka_shm->core_state[idx_core] =
64 					RTE_KA_STATE_UNUSED;
65 				ka_shm->core_last_seen_times[idx_core] = 0;
66 			}
67 
68 			return ka_shm;
69 		}
70 	}
71 return NULL;
72 }
73 
rte_keepalive_relayed_state(struct rte_keepalive_shm * shm,const int id_core,const enum rte_keepalive_state core_state,__rte_unused uint64_t last_alive)74 void rte_keepalive_relayed_state(struct rte_keepalive_shm *shm,
75 	const int id_core, const enum rte_keepalive_state core_state,
76 	__rte_unused uint64_t last_alive)
77 {
78 	int count;
79 
80 	shm->core_state[id_core] = core_state;
81 	shm->core_last_seen_times[id_core] = last_alive;
82 
83 	if (core_state == RTE_KEEPALIVE_SHM_DEAD) {
84 		/* Since core has died, also signal ka_agent.
85 		 *
86 		 * Limit number of times semaphore can be incremented, in case
87 		 * ka_agent is not active.
88 		 */
89 		if (sem_getvalue(&shm->core_died, &count) == -1) {
90 			RTE_LOG(INFO, EAL, "Semaphore check failed(%s)\n",
91 				strerror(errno));
92 			return;
93 		}
94 		if (count > 1)
95 			return;
96 
97 		if (sem_post(&shm->core_died) != 0)
98 			RTE_LOG(INFO, EAL,
99 				"Failed to increment semaphore (%s)\n",
100 				strerror(errno));
101 	}
102 }
103 
rte_keepalive_shm_cleanup(struct rte_keepalive_shm * ka_shm)104 void rte_keepalive_shm_cleanup(struct rte_keepalive_shm *ka_shm)
105 {
106 	if (shm_unlink(RTE_KEEPALIVE_SHM_NAME) == -1 && errno != ENOENT)
107 		printf("Warning: Error unlinking  %s (%s)\n",
108 			RTE_KEEPALIVE_SHM_NAME, strerror(errno));
109 
110 	if (ka_shm && munmap(ka_shm, sizeof(struct rte_keepalive_shm)) != 0)
111 		printf("Warning: munmap() failed\n");
112 }
113