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 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 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 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