From: Philippe Gerum <[email protected]> Unlike the I-pipe, Dovetail does not copy the work descriptor but merely hands over the request to the common irq_work() mechanism. We must guarantee that such descriptor lives in a portion of memory which won't go stale until the handler has run, which by design can only happen once the calling out-of-band context unwinds.
Therefore, we have to move the in-band work descriptor used in triggering fd closure off the stack to a global variable, which is fine since the action of flushing the lingering fds is globally scoped. Signed-off-by: Philippe Gerum <[email protected]> Signed-off-by: Jan Kiszka <[email protected]> --- kernel/cobalt/rtdm/fd.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/kernel/cobalt/rtdm/fd.c b/kernel/cobalt/rtdm/fd.c index 038247d54..151884a24 100644 --- a/kernel/cobalt/rtdm/fd.c +++ b/kernel/cobalt/rtdm/fd.c @@ -257,10 +257,6 @@ out: } EXPORT_SYMBOL_GPL(rtdm_fd_get); -struct lostage_trigger_close { - struct pipeline_inband_work inband_work; /* Must be first. */ -}; - static int fd_cleanup_thread(void *data) { struct rtdm_fd *fd; @@ -293,9 +289,16 @@ static void lostage_trigger_close(struct pipeline_inband_work *inband_work) up(&rtdm_fd_cleanup_sem); } +static struct lostage_trigger_close { + struct pipeline_inband_work inband_work; /* Must be first. */ +} fd_closework = { + .inband_work = PIPELINE_INBAND_WORK_INITIALIZER(fd_closework, + lostage_trigger_close), +}; + static void __put_fd(struct rtdm_fd *fd, spl_t s) { - bool destroy; + bool destroy, trigger; XENO_WARN_ON(COBALT, fd->refs <= 0); destroy = --fd->refs == 0; @@ -310,16 +313,13 @@ static void __put_fd(struct rtdm_fd *fd, spl_t s) if (is_secondary_domain()) fd->ops->close(fd); else { - struct lostage_trigger_close closework = { - .inband_work = PIPELINE_INBAND_WORK_INITIALIZER(closework, - lostage_trigger_close), - }; - xnlock_get_irqsave(&fdtree_lock, s); + trigger = list_empty(&rtdm_fd_cleanup_queue); list_add_tail(&fd->cleanup, &rtdm_fd_cleanup_queue); xnlock_put_irqrestore(&fdtree_lock, s); - pipeline_post_inband_work(&closework); + if (trigger) + pipeline_post_inband_work(&fd_closework); } } -- 2.26.2
