Re-implements reverted commit 344f7bc9f6 in a way that should not have the undesired side-effect. include/nuttx/sched.h: Add a bit to the TCB flags to indicat the thread is a user thread in a syscall. sched/nuttx/nxsig_dispatch.c: Delay dispatching to signal handlers if within a system call. In all syscall implementations: Process delayed signal handling when exiting system call.

This commit is contained in:
Gregory Nutt 2019-11-28 12:47:36 -06:00
parent cbdd590c82
commit 69318b1024
13 changed files with 147 additions and 40 deletions

View file

@ -1,7 +1,7 @@
/****************************************************************************
* arch/arm/src/armv6-m/up_svcall.c
*
* Copyright (C) 2013-2014 Gregory Nutt. All rights reserved.
* Copyright (C) 2013-2014, 2019 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -51,6 +51,7 @@
# include <syscall.h>
#endif
#include "signal/signal.h"
#include "svcall.h"
#include "exc_return.h"
#include "up_internal.h"
@ -269,6 +270,13 @@ int up_svcall(int irq, FAR void *context, FAR void *arg)
*/
regs[REG_R0] = regs[REG_R2];
/* Handle any signal actions that were deferred while processing
* the system call.
*/
rtcb->flags &= ~TCB_FLAG_SYSCALL;
(void)nxsig_unmask_pendingsignal();
}
break;
#endif
@ -437,7 +445,11 @@ int up_svcall(int irq, FAR void *context, FAR void *arg)
/* Offset R0 to account for the reserved values */
regs[REG_R0] -= CONFIG_SYS_RESERVED;
regs[REG_R0] -= CONFIG_SYS_RESERVED;
/* Indicate that we are in a syscall handler. */
rtcb->flags |= TCB_FLAG_SYSCALL;
#else
svcerr("ERROR: Bad SYS call: %d\n", regs[REG_R0]);
#endif

View file

@ -1,7 +1,7 @@
/****************************************************************************
* arch/arm/src/armv7-a/arm_syscall.c
*
* Copyright (C) 2013-2014, 2016 Gregory Nutt. All rights reserved.
* Copyright (C) 2013-2014, 2016, 2019 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -49,6 +49,7 @@
#include <nuttx/sched.h>
#include <nuttx/addrenv.h>
#include "signal/signal.h"
#include "arm.h"
#include "svcall.h"
#include "addrenv.h"
@ -218,7 +219,14 @@ uint32_t *arm_syscall(uint32_t *regs)
#endif
/* Save the new SYSCALL nesting level */
rtcb->xcp.nsyscalls = index;
rtcb->xcp.nsyscalls = index;
/* Handle any signal actions that were deferred while processing
* the system call.
*/
rtcb->flags &= ~TCB_FLAG_SYSCALL;
(void)nxsig_unmask_pendingsignal();
}
break;
@ -449,7 +457,11 @@ uint32_t *arm_syscall(uint32_t *regs)
#endif
/* Offset R0 to account for the reserved values */
regs[REG_R0] -= CONFIG_SYS_RESERVED;
regs[REG_R0] -= CONFIG_SYS_RESERVED;
/* Indicate that we are in a syscall handler. */
rtcb->flags |= TCB_FLAG_SYSCALL;
#else
svcerr("ERROR: Bad SYS call: %d\n", regs[REG_R0]);
#endif

View file

@ -1,7 +1,7 @@
/****************************************************************************
* arch/arm/src/armv7-m/up_svcall.c
*
* Copyright (C) 2009, 2011-2015 Gregory Nutt. All rights reserved.
* Copyright (C) 2009, 2011-2015, 2019 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -52,6 +52,7 @@
# include <syscall.h>
#endif
#include "signal/signal.h"
#include "svcall.h"
#include "exc_return.h"
#include "up_internal.h"
@ -269,6 +270,13 @@ int up_svcall(int irq, FAR void *context, FAR void *arg)
*/
regs[REG_R0] = regs[REG_R2];
/* Handle any signal actions that were deferred while processing
* the system call.
*/
rtcb->flags &= ~TCB_FLAG_SYSCALL;
(void)nxsig_unmask_pendingsignal();
}
break;
#endif
@ -437,7 +445,11 @@ int up_svcall(int irq, FAR void *context, FAR void *arg)
/* Offset R0 to account for the reserved values */
regs[REG_R0] -= CONFIG_SYS_RESERVED;
regs[REG_R0] -= CONFIG_SYS_RESERVED;
/* Indicate that we are in a syscall handler. */
rtcb->flags |= TCB_FLAG_SYSCALL;
#else
svcerr("ERROR: Bad SYS call: %d\n", regs[REG_R0]);
#endif

View file

@ -1,7 +1,7 @@
/****************************************************************************
* arch/arm/src/armv7-r/arm_syscall.c
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Copyright (C) 2015, 20-19 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -48,6 +48,7 @@
#include <arch/irq.h>
#include <nuttx/sched.h>
#include "signal/signal.h"
#include "arm.h"
#include "svcall.h"
#include "up_internal.h"
@ -216,7 +217,14 @@ uint32_t *arm_syscall(uint32_t *regs)
#endif
/* Save the new SYSCALL nesting level */
rtcb->xcp.nsyscalls = index;
rtcb->xcp.nsyscalls = index;
/* Handle any signal actions that were deferred while processing
* the system call.
*/
rtcb->flags &= ~TCB_FLAG_SYSCALL;
(void)nxsig_unmask_pendingsignal();
}
break;
@ -447,7 +455,11 @@ uint32_t *arm_syscall(uint32_t *regs)
#endif
/* Offset R0 to account for the reserved values */
regs[REG_R0] -= CONFIG_SYS_RESERVED;
regs[REG_R0] -= CONFIG_SYS_RESERVED;
/* Indicate that we are in a syscall handler. */
rtcb->flags |= TCB_FLAG_SYSCALL;
#else
svcerr("ERROR: Bad SYS call: %d\n", regs[REG_R0]);
#endif

View file

@ -1,7 +1,7 @@
/****************************************************************************
* arch/mips/src/mips32/up_swint0.c
*
* Copyright (C) 2011-2012, 2015 Gregory Nutt. All rights reserved.
* Copyright (C) 2011-2012, 2015, 2019 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -50,6 +50,7 @@
#include <arch/irq.h>
#include <arch/mips32/cp0.h>
#include "signal/signal.h"
#include "up_internal.h"
/****************************************************************************
@ -224,7 +225,14 @@ int up_swint0(int irq, FAR void *context, FAR void *arg)
g_current_regs[REG_EPC] = rtcb->xcp.syscall[index].sysreturn;
#error "Missing logic -- need to restore the original mode"
rtcb->xcp.nsyscalls = index;
rtcb->xcp.nsyscalls = index;
/* Handle any signal actions that were deferred while processing
* the system call.
*/
rtcb->flags &= ~TCB_FLAG_SYSCALL;
(void)nxsig_unmask_pendingsignal();
}
break;
#endif
@ -256,12 +264,16 @@ int up_swint0(int irq, FAR void *context, FAR void *arg)
#error "Missing logic -- Need to save mode"
rtcb->xcp.nsyscalls = index + 1;
regs[REG_EPC] = (uint32_t)dispatch_syscall;
regs[REG_EPC] = (uint32_t)dispatch_syscall;
#error "Missing logic -- Need to set privileged mode"
/* Offset R0 to account for the reserved values */
g_current_regs[REG_R0] -= CONFIG_SYS_RESERVED;
/* Indicate that we are in a syscall handler. */
rtcb->flags |= TCB_FLAG_SYSCALL;
#else
svcerr("ERROR: Bad SYS call: %d\n", regs[REG_A0]);
#endif

View file

@ -1,7 +1,7 @@
/****************************************************************************
* arch/misoc/src/lm32/lm32_swint.c
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Copyright (C) 2016, 2019 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* Ramtin Amin <keytwo@gmail.com>
*
@ -49,6 +49,7 @@
#include <nuttx/sched.h>
#include <arch/irq.h>
#include "signal/signal.h"
#include "lm32.h"
/****************************************************************************
@ -225,7 +226,14 @@ int lm32_swint(int irq, FAR void *context, FAR void *arg)
g_current_regs[REG_EPC] = rtcb->xcp.syscall[index].sysreturn;
#error "Missing logic -- need to restore the original mode"
rtcb->xcp.nsyscalls = index;
rtcb->xcp.nsyscalls = index;
/* Handle any signal actions that were deferred while processing
* the system call.
*/
rtcb->flags &= ~TCB_FLAG_SYSCALL;
(void)nxsig_unmask_pendingsignal();
}
break;
#endif
@ -257,12 +265,16 @@ int lm32_swint(int irq, FAR void *context, FAR void *arg)
#error "Missing logic -- Need to save mode"
rtcb->xcp.nsyscalls = index + 1;
regs[REG_EPC] = (uint32_t)dispatch_syscall;
regs[REG_EPC] = (uint32_t)dispatch_syscall;
#error "Missing logic -- Need to set privileged mode"
/* Offset R0 to account for the reserved values */
g_current_regs[REG_A0] -= CONFIG_SYS_RESERVED;
/* Indicate that we are in a syscall handler. */
rtcb->flags |= TCB_FLAG_SYSCALL;
#else
svcerr("ERROR: Bad SYS call: %d\n", regs[REG_A0]);
#endif

View file

@ -49,6 +49,7 @@
#include <nuttx/sched.h>
#include <arch/irq.h>
#include "signal/signal.h"
#include "minerva.h"
/****************************************************************************
@ -212,7 +213,14 @@ int minerva_swint(int irq, FAR void *context, FAR void *arg)
g_current_regs[REG_CSR_MEPC] = rtcb->xcp.syscall[index].sysreturn;
#error "Missing logic -- need to restore the original mode"
rtcb->xcp.nsyscalls = index;
rtcb->xcp.nsyscalls = index;
/* Handle any signal actions that were deferred while processing
* the system call.
*/
rtcb->flags &= ~TCB_FLAG_SYSCALL;
(void)nxsig_unmask_pendingsignal();
}
break;
#endif
@ -245,12 +253,16 @@ int minerva_swint(int irq, FAR void *context, FAR void *arg)
#error "Missing logic -- Need to save mode"
rtcb->xcp.nsyscalls = index + 1;
regs[REG_CSR_MEPC] = (uint32_t) dispatch_syscall;
regs[REG_CSR_MEPC] = (uint32_t) dispatch_syscall;
#error "Missing logic -- Need to set privileged mode"
/* Offset R0 to account for the reserved values */
g_current_regs[REG_A0] -= CONFIG_SYS_RESERVED;
/* Indicate that we are in a syscall handler. */
rtcb->flags |= TCB_FLAG_SYSCALL;
#else
svcerr("ERROR: Bad SYS call: %d\n", regs[REG_A0]);
#endif

View file

@ -1,7 +1,7 @@
/****************************************************************************
* arch/riscv/src/rv32im/up_swint.c
*
* Copyright (C) 2011-2012, 2015 Gregory Nutt. All rights reserved.
* Copyright (C) 2011-2012, 2015, 2019 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -49,6 +49,7 @@
#include <arch/irq.h>
#include "signal/signal.h"
#include "up_internal.h"
/****************************************************************************
@ -222,7 +223,14 @@ int up_swint(int irq, FAR void *context, FAR void *arg)
g_current_regs[REG_EPC] = rtcb->xcp.syscall[index].sysreturn;
#error "Missing logic -- need to restore the original mode"
rtcb->xcp.nsyscalls = index;
rtcb->xcp.nsyscalls = index;
/* Handle any signal actions that were deferred while processing
* the system call.
*/
rtcb->flags &= ~TCB_FLAG_SYSCALL;
(void)nxsig_unmask_pendingsignal();
}
break;
#endif
@ -254,12 +262,16 @@ int up_swint(int irq, FAR void *context, FAR void *arg)
#error "Missing logic -- Need to save mode"
rtcb->xcp.nsyscalls = index + 1;
regs[REG_EPC] = (uint32_t)dispatch_syscall;
regs[REG_EPC] = (uint32_t)dispatch_syscall;
#error "Missing logic -- Need to set privileged mode"
/* Offset R0 to account for the reserved values */
g_current_regs[REG_A0] -= CONFIG_SYS_RESERVED;
/* Indicate that we are in a syscall handler. */
rtcb->flags |= TCB_FLAG_SYSCALL;
#else
svcerr("ERROR: Bad SYS call: %d\n", regs[REG_A0]);
#endif

View file

@ -103,24 +103,25 @@
/* Values for the struct tcb_s flags bits */
#define TCB_FLAG_TTYPE_SHIFT (0) /* Bits 0-1: thread type */
#define TCB_FLAG_TTYPE_SHIFT (0) /* Bits 0-1: thread type */
#define TCB_FLAG_TTYPE_MASK (3 << TCB_FLAG_TTYPE_SHIFT)
# define TCB_FLAG_TTYPE_TASK (0 << TCB_FLAG_TTYPE_SHIFT) /* Normal user task */
# define TCB_FLAG_TTYPE_PTHREAD (1 << TCB_FLAG_TTYPE_SHIFT) /* User pthread */
# define TCB_FLAG_TTYPE_KERNEL (2 << TCB_FLAG_TTYPE_SHIFT) /* Kernel thread */
#define TCB_FLAG_NONCANCELABLE (1 << 2) /* Bit 2: Pthread is non-cancelable */
#define TCB_FLAG_CANCEL_DEFERRED (1 << 3) /* Bit 3: Deferred (vs asynch) cancellation type */
#define TCB_FLAG_CANCEL_PENDING (1 << 4) /* Bit 4: Pthread cancel is pending */
#define TCB_FLAG_POLICY_SHIFT (5) /* Bit 5-6: Scheduling policy */
#define TCB_FLAG_NONCANCELABLE (1 << 2) /* Bit 2: Pthread is non-cancelable */
#define TCB_FLAG_CANCEL_DEFERRED (1 << 3) /* Bit 3: Deferred (vs asynch) cancellation type */
#define TCB_FLAG_CANCEL_PENDING (1 << 4) /* Bit 4: Pthread cancel is pending */
#define TCB_FLAG_POLICY_SHIFT (5) /* Bit 5-6: Scheduling policy */
#define TCB_FLAG_POLICY_MASK (3 << TCB_FLAG_POLICY_SHIFT)
# define TCB_FLAG_SCHED_FIFO (0 << TCB_FLAG_POLICY_SHIFT) /* FIFO scheding policy */
# define TCB_FLAG_SCHED_RR (1 << TCB_FLAG_POLICY_SHIFT) /* Round robin scheding policy */
# define TCB_FLAG_SCHED_SPORADIC (2 << TCB_FLAG_POLICY_SHIFT) /* Sporadic scheding policy */
# define TCB_FLAG_SCHED_OTHER (3 << TCB_FLAG_POLICY_SHIFT) /* Other scheding policy */
#define TCB_FLAG_CPU_LOCKED (1 << 7) /* Bit 7: Locked to this CPU */
#define TCB_FLAG_SIGNAL_ACTION (1 << 8) /* Bit 8: In a signal handler */
#define TCB_FLAG_EXIT_PROCESSING (1 << 9) /* Bit 9: Exitting */
/* Bits 10-15: Available */
#define TCB_FLAG_CPU_LOCKED (1 << 7) /* Bit 7: Locked to this CPU */
#define TCB_FLAG_SIGNAL_ACTION (1 << 8) /* Bit 8: In a signal handler */
#define TCB_FLAG_SYSCALL (1 << 9) /* Bit 9: In a system call */
#define TCB_FLAG_EXIT_PROCESSING (1 << 10) /* Bit 10: Exitting */
/* Bits 11-15: Available */
/* Values for struct task_group tg_flags */

View file

@ -127,8 +127,8 @@ static void netlink_notify_waiters(FAR struct netlink_conn_s *conn)
int i;
/* Notify every pending thread. Lock the scheduler while we do this so
* there there is no thrashing: All waiters will be restarted, but only
* the highest priority waiter will get to run and will receive the
* that there is no thrashing: All waiters will be restarted, but only
* the highest priority waiter will get to run and it will receive the
* response.
*/

View file

@ -640,8 +640,10 @@ static int netlink_poll(FAR struct socket *psock, FAR struct pollfd *fds,
{
struct sigaction act;
/* Set up a signal handler to recive the notification when
/* Set up a signal handler to receive the notification when
* a response has been queued.
* REVISIT: Make sure that the CONFIG_NETLINK_SIGNAL is not
* blocked.
*/
if (conn->pollsem != NULL || conn->pollevent != NULL)

View file

@ -1,8 +1,8 @@
/****************************************************************************
* sched/signal/sig_dispatch.c
*
* Copyright (C) 2007, 2009, 2011, 2016, 2018 Gregory Nutt. All rights
* reserved.
* Copyright (C) 2007, 2009, 2011, 2016, 2018-2019 Gregory Nutt. All
* rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -311,11 +311,13 @@ int nxsig_tcbdispatch(FAR struct tcb_s *stcb, siginfo_t *info)
/************************* MASKED SIGNAL HANDLING ************************/
/* Check if the signal is masked -- if it is, it will be added to the list
* of pending signals.
/* Check if the signal is masked OR if it is received while we are
* processing a system call -- in either case, it will be added to the
* list of pending signals.
*/
if (sigismember(&stcb->sigprocmask, info->si_signo))
if (sigismember(&stcb->sigprocmask, info->si_signo) ||
(stcb->flags & TCB_FLAG_SYSCALL) != NULL)
{
/* Check if the task is waiting for this pending signal. If so, then
* unblock it. This must be performed in a critical section because
@ -380,9 +382,16 @@ int nxsig_tcbdispatch(FAR struct tcb_s *stcb, siginfo_t *info)
* handler attached to the signal, then the default action is
* simply to ignore the signal
*/
}
/*********************** OTHER SIGNAL HANDLING ***********************/
/************************* OTHER SIGNAL HANDLING *************************/
/* Performed only if the signal is unmasked. These actions also must
* happen within a system call.
*/
if (!sigismember(&stcb->sigprocmask, info->si_signo))
{
/* If the task is blocked waiting for a semaphore, then that task must
* be unblocked when a signal is received.
*/

View file

@ -127,4 +127,3 @@ bool nxsig_unmask_pendingsignal(void)
sched_unlock();
return true;
}