sim/sim_rptun: Support master/slave notifies opposite side when recovery

When in a multi-core structure, as the intermediate core,
remote is both the master and slave;When the remote exception or
restart occurs, it needs to notify the slave and reestablish the connection

Signed-off-by: yintao <yintao@xiaomi.com>
This commit is contained in:
yintao 2023-11-29 00:18:47 +08:00 committed by archer
parent a20cc9f04c
commit 4f14f8226a
5 changed files with 78 additions and 34 deletions

View File

@ -92,32 +92,20 @@ void host_freeheap(void *mem)
host_uninterruptible(munmap, mem, 0); host_uninterruptible(munmap, mem, 0);
} }
void *host_allocshmem(const char *name, size_t size, int master) void *host_allocshmem(const char *name, size_t size)
{ {
void *mem; void *mem;
int oflag; int oflag;
int ret; int ret;
int fd; int fd;
oflag = O_RDWR; oflag = O_RDWR | O_CREAT;
if (master)
{
oflag |= O_CREAT | O_TRUNC;
}
fd = host_uninterruptible(shm_open, name, oflag, S_IRUSR | S_IWUSR); fd = host_uninterruptible(shm_open, name, oflag, S_IRUSR | S_IWUSR);
if (fd < 0) if (fd < 0)
{ {
return NULL; return NULL;
} }
if (!master)
{
/* Avoid the second slave instance open successfully */
host_unlinkshmem(name);
}
ret = host_uninterruptible(ftruncate, fd, size); ret = host_uninterruptible(ftruncate, fd, size);
if (ret < 0) if (ret < 0)
{ {

View File

@ -224,7 +224,7 @@ int host_waitpid(pid_t pid);
void *host_allocheap(size_t size, bool exec); void *host_allocheap(size_t size, bool exec);
void host_freeheap(void *mem); void host_freeheap(void *mem);
void *host_allocshmem(const char *name, size_t size, int master); void *host_allocshmem(const char *name, size_t size);
void host_freeshmem(void *mem); void host_freeshmem(void *mem);
size_t host_mallocsize(void *mem); size_t host_mallocsize(void *mem);

View File

@ -40,6 +40,12 @@
#define SIM_RPTUN_SHIFT 16 #define SIM_RPTUN_SHIFT 16
#define SIM_RPTUN_WORK_DELAY 1 #define SIM_RPTUN_WORK_DELAY 1
/* Status byte for master/slave to report progress */
#define SIM_RPTUN_STATUS_BOOT 0x01
#define SIM_RPTUN_STATUS_OK 0x02
#define SIM_RPTUN_STATUS_NEED_RESET 0x04
/**************************************************************************** /****************************************************************************
* Private Types * Private Types
****************************************************************************/ ****************************************************************************/
@ -51,6 +57,8 @@ struct sim_rptun_shmem_s
volatile unsigned int seqm; volatile unsigned int seqm;
volatile unsigned int cmds; volatile unsigned int cmds;
volatile unsigned int cmdm; volatile unsigned int cmdm;
volatile unsigned int boots;
volatile unsigned int bootm;
struct rptun_rsc_s rsc; struct rptun_rsc_s rsc;
char buf[0x10000]; char buf[0x10000];
}; };
@ -91,24 +99,14 @@ sim_rptun_get_resource(struct rptun_dev_s *dev)
struct sim_rptun_dev_s *priv = container_of(dev, struct sim_rptun_dev_s *priv = container_of(dev,
struct sim_rptun_dev_s, rptun); struct sim_rptun_dev_s, rptun);
if (priv->shmem) priv->shmem = host_allocshmem(priv->shmemname,
{ sizeof(*priv->shmem));
return &priv->shmem->rsc;
}
while (priv->shmem == NULL)
{
priv->shmem = host_allocshmem(priv->shmemname,
sizeof(*priv->shmem),
priv->master);
usleep(1000);
/* Master isn't ready, sleep and try again */
}
if (priv->master) if (priv->master)
{ {
struct rptun_rsc_s *rsc = &priv->shmem->rsc; struct rptun_rsc_s *rsc = &priv->shmem->rsc;
memset(priv->shmem->buf, 0, sizeof(priv->shmem->buf));
memset(rsc, 0, sizeof(struct rptun_rsc_s));
rsc->rsc_tbl_hdr.ver = 1; rsc->rsc_tbl_hdr.ver = 1;
rsc->rsc_tbl_hdr.num = 1; rsc->rsc_tbl_hdr.num = 1;
@ -121,9 +119,11 @@ sim_rptun_get_resource(struct rptun_dev_s *dev)
| 1 << VIRTIO_RPMSG_F_BUFSZ; | 1 << VIRTIO_RPMSG_F_BUFSZ;
rsc->rpmsg_vdev.config_len = sizeof(struct fw_rsc_config); rsc->rpmsg_vdev.config_len = sizeof(struct fw_rsc_config);
rsc->rpmsg_vdev.num_of_vrings = 2; rsc->rpmsg_vdev.num_of_vrings = 2;
rsc->rpmsg_vring0.da = 0;
rsc->rpmsg_vring0.align = 8; rsc->rpmsg_vring0.align = 8;
rsc->rpmsg_vring0.num = 8; rsc->rpmsg_vring0.num = 8;
rsc->rpmsg_vring0.notifyid = RSC_NOTIFY_ID_ANY; rsc->rpmsg_vring0.notifyid = RSC_NOTIFY_ID_ANY;
rsc->rpmsg_vring1.da = 0;
rsc->rpmsg_vring1.align = 8; rsc->rpmsg_vring1.align = 8;
rsc->rpmsg_vring1.num = 8; rsc->rpmsg_vring1.num = 8;
rsc->rpmsg_vring1.notifyid = RSC_NOTIFY_ID_ANY; rsc->rpmsg_vring1.notifyid = RSC_NOTIFY_ID_ANY;
@ -131,16 +131,36 @@ sim_rptun_get_resource(struct rptun_dev_s *dev)
rsc->config.h2r_buf_size = 0x800; rsc->config.h2r_buf_size = 0x800;
priv->shmem->base = (uintptr_t)priv->shmem; priv->shmem->base = (uintptr_t)priv->shmem;
/* The master notifies its slave when it starts again */
if (priv->shmem->boots & SIM_RPTUN_STATUS_OK)
{
priv->shmem->boots = SIM_RPTUN_STATUS_NEED_RESET;
}
priv->shmem->bootm = SIM_RPTUN_STATUS_BOOT;
} }
else else
{ {
/* The slave notifies its master when it starts again */
if (priv->shmem->boots & SIM_RPTUN_STATUS_OK)
{
priv->shmem->bootm = SIM_RPTUN_STATUS_NEED_RESET;
}
priv->shmem->boots = SIM_RPTUN_STATUS_BOOT;
/* Wait untils master is ready */ /* Wait untils master is ready */
while (priv->shmem->base == 0) while (!(priv->shmem->bootm & SIM_RPTUN_STATUS_OK))
{ {
usleep(1000); usleep(1000);
} }
priv->shmem->boots = SIM_RPTUN_STATUS_OK;
priv->addrenv[0].va = (uintptr_t)priv->shmem; priv->addrenv[0].va = (uintptr_t)priv->shmem;
priv->addrenv[0].pa = priv->shmem->base; priv->addrenv[0].pa = priv->shmem->base;
priv->addrenv[0].size = sizeof(*priv->shmem); priv->addrenv[0].size = sizeof(*priv->shmem);
@ -180,6 +200,14 @@ static int sim_rptun_start(struct rptun_dev_s *dev)
priv->pid = pid; priv->pid = pid;
} }
/* Wait until slave has started */
while (!(priv->shmem->boots & SIM_RPTUN_STATUS_BOOT))
{
usleep(1000);
}
priv->shmem->bootm = SIM_RPTUN_STATUS_OK;
return 0; return 0;
} }
@ -188,13 +216,21 @@ static int sim_rptun_stop(struct rptun_dev_s *dev)
struct sim_rptun_dev_s *priv = container_of(dev, struct sim_rptun_dev_s *priv = container_of(dev,
struct sim_rptun_dev_s, rptun); struct sim_rptun_dev_s, rptun);
if ((priv->master & SIM_RPTUN_BOOT) && (priv->pid > 0)) /* Don't send SIM_RPTUN_STOP when slave recovery */
if (priv->shmem->boots & SIM_RPTUN_STATUS_OK)
{ {
priv->shmem->cmdm = SIM_RPTUN_STOP << SIM_RPTUN_SHIFT; priv->shmem->cmdm = SIM_RPTUN_STOP << SIM_RPTUN_SHIFT;
}
if ((priv->master & SIM_RPTUN_BOOT) && priv->pid > 0)
{
host_waitpid(priv->pid); host_waitpid(priv->pid);
} }
if (priv->shmem) /* Master cleans shmem when both sides are about to exit */
if (priv->shmem && (priv->shmem->boots & SIM_RPTUN_STATUS_OK))
{ {
host_freeshmem(priv->shmem); host_freeshmem(priv->shmem);
priv->shmem = NULL; priv->shmem = NULL;
@ -267,6 +303,22 @@ static void sim_rptun_check_cmd(struct sim_rptun_dev_s *priv)
} }
} }
static void sim_rptun_check_reset(struct sim_rptun_dev_s *priv)
{
if (priv->master &&
(priv->shmem->bootm & SIM_RPTUN_STATUS_NEED_RESET))
{
priv->shmem->bootm = 0;
rptun_boot(priv->cpuname);
}
else if (!priv->master &&
(priv->shmem->boots & SIM_RPTUN_STATUS_NEED_RESET))
{
priv->shmem->boots = 0;
rptun_boot(priv->cpuname);
}
}
static void sim_rptun_work(void *arg) static void sim_rptun_work(void *arg)
{ {
struct sim_rptun_dev_s *dev = arg; struct sim_rptun_dev_s *dev = arg;
@ -277,6 +329,10 @@ static void sim_rptun_work(void *arg)
sim_rptun_check_cmd(dev); sim_rptun_check_cmd(dev);
/* Check if master/slave need to reset */
sim_rptun_check_reset(dev);
if (dev->master && dev->seq != dev->shmem->seqs) if (dev->master && dev->seq != dev->shmem->seqs)
{ {
dev->seq = dev->shmem->seqs; dev->seq = dev->shmem->seqs;

View File

@ -675,7 +675,7 @@ static int sim_uartram_register(const char *devname, bool slave)
struct uart_rambuf_s *shmem; struct uart_rambuf_s *shmem;
strlcpy(name, strrchr(devname, '/') + 1, NAME_MAX); strlcpy(name, strrchr(devname, '/') + 1, NAME_MAX);
shmem = host_allocshmem(name, sizeof(struct uart_rambuf_s) * 2, !slave); shmem = host_allocshmem(name, sizeof(struct uart_rambuf_s) * 2);
DEBUGASSERT(shmem); DEBUGASSERT(shmem);
memset(shmem, 0, sizeof(struct uart_rambuf_s) * 2); memset(shmem, 0, sizeof(struct uart_rambuf_s) * 2);

View File

@ -56,7 +56,7 @@ void host_freeheap(void *mem)
_aligned_free(mem); _aligned_free(mem);
} }
void *host_allocshmem(const char *name, size_t size, int master) void *host_allocshmem(const char *name, size_t size)
{ {
HANDLE handle; HANDLE handle;
void *mem; void *mem;