summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2020-12-01 22:53:33 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2020-12-01 22:53:33 +0000
commit6814c2dac5741e500a600330306e424b0b64e5f0 (patch)
tree92cada2eb65e3b65c06bdb3c22755d37c4262b65 /sys/kern
parent29331656668c8c5e3b4bd3c0ab02cd64887c6b19 (diff)
downloadsrc-test2-6814c2dac5741e500a600330306e424b0b64e5f0.tar.gz
src-test2-6814c2dac5741e500a600330306e424b0b64e5f0.zip
lio_listio(2): send signal even if number of jobs is zero.
Right now, if lio registered zero jobs, syscall frees lio job structure, cleaning up queued ksi. As result, the realtime signal is dequeued and never delivered. Fix it by allowing sendsig() to copy ksi when job count is zero. PR: 220398 Reported and reviewed by: asomers Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D27421
Notes
Notes: svn path=/head/; revision=368265
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/vfs_aio.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c
index 7b725734d188..6c70714d5421 100644
--- a/sys/kern/vfs_aio.c
+++ b/sys/kern/vfs_aio.c
@@ -466,7 +466,7 @@ aio_init_aioinfo(struct proc *p)
}
static int
-aio_sendsig(struct proc *p, struct sigevent *sigev, ksiginfo_t *ksi)
+aio_sendsig(struct proc *p, struct sigevent *sigev, ksiginfo_t *ksi, bool ext)
{
struct thread *td;
int error;
@@ -477,7 +477,7 @@ aio_sendsig(struct proc *p, struct sigevent *sigev, ksiginfo_t *ksi)
if (!KSI_ONQ(ksi)) {
ksiginfo_set_sigev(ksi, sigev);
ksi->ksi_code = SI_ASYNCIO;
- ksi->ksi_flags |= KSI_EXT | KSI_INS;
+ ksi->ksi_flags |= ext ? (KSI_EXT | KSI_INS) : 0;
tdsendsignal(p, td, ksi->ksi_signo, ksi);
}
PROC_UNLOCK(p);
@@ -896,7 +896,7 @@ aio_bio_done_notify(struct proc *userp, struct kaiocb *job)
if (job->uaiocb.aio_sigevent.sigev_notify == SIGEV_SIGNAL ||
job->uaiocb.aio_sigevent.sigev_notify == SIGEV_THREAD_ID)
- aio_sendsig(userp, &job->uaiocb.aio_sigevent, &job->ksi);
+ aio_sendsig(userp, &job->uaiocb.aio_sigevent, &job->ksi, true);
KNOTE_LOCKED(&job->klist, 1);
@@ -909,7 +909,8 @@ aio_bio_done_notify(struct proc *userp, struct kaiocb *job)
== LIOJ_SIGNAL &&
(lj->lioj_signal.sigev_notify == SIGEV_SIGNAL ||
lj->lioj_signal.sigev_notify == SIGEV_THREAD_ID)) {
- aio_sendsig(userp, &lj->lioj_signal, &lj->lioj_ksi);
+ aio_sendsig(userp, &lj->lioj_signal, &lj->lioj_ksi,
+ true);
lj->lioj_flags |= LIOJ_SIGNAL_POSTED;
}
}
@@ -2238,7 +2239,8 @@ kern_lio_listio(struct thread *td, int mode, struct aiocb * const *uacb_list,
LIOJ_SIGNAL_POSTED)) == LIOJ_SIGNAL &&
(lj->lioj_signal.sigev_notify == SIGEV_SIGNAL ||
lj->lioj_signal.sigev_notify == SIGEV_THREAD_ID)) {
- aio_sendsig(p, &lj->lioj_signal, &lj->lioj_ksi);
+ aio_sendsig(p, &lj->lioj_signal, &lj->lioj_ksi,
+ lj->lioj_count != 1);
lj->lioj_flags |= LIOJ_SIGNAL_POSTED;
}
}