Priority inversion occurs because processing thread for logsys takes
spinlock at prio 0, then is preempted by a sched_rr:99 process which
log_printfs, which takes spinlock and deadlocks the system because the
lower priority thread with spinlock held is never scheduled again.
This patch adds a logsys api to override the default scheduling priority
of the logsys thread and integrates it into main.c.
Index: include/corosync/engine/logsys.h
===================================================================
--- include/corosync/engine/logsys.h (revision 2126)
+++ include/corosync/engine/logsys.h (working copy)
@@ -40,6 +40,7 @@
#include <stdarg.h>
#include <stdlib.h>
#include <syslog.h>
+#include <pthread.h>
/*
* All of the LOGSYS_MODE's can be ORed together for combined behavior
@@ -242,6 +243,10 @@
extern const char *logsys_tag_name_get (
unsigned int tag);
+extern int logsys_thread_priority_set (
+ int policy,
+ const struct sched_param *param);
+
/*
* External definitions
*/
Index: exec/mainconfig.c
===================================================================
--- exec/mainconfig.c (revision 2126)
+++ exec/mainconfig.c (working copy)
@@ -722,8 +722,6 @@
add_logsys_config_notification(objdb);
- logsys_fork_completed ();
-
return 0;
parse_error:
Index: exec/logsys.c
===================================================================
--- exec/logsys.c (revision 2126)
+++ exec/logsys.c (working copy)
@@ -1439,6 +1439,17 @@
return (NULL);
}
+int logsys_thread_priority_set (
+ int policy,
+ const struct sched_param *param)
+{
+ int res;
+
+ res = pthread_setschedparam (logsys_thread_id, policy, param);
+ return (res);
+
+}
+
int logsys_log_rec_store (const char *filename)
{
int fd;
Index: exec/main.c
===================================================================
--- exec/main.c (revision 2126)
+++ exec/main.c (working copy)
@@ -128,6 +128,8 @@
hdb_handle_t corosync_poll_handle;
+struct sched_param global_sched_param;
+
static void sigusr2_handler (int num)
{
int i;
@@ -369,16 +371,15 @@
static void corosync_setscheduler (void)
{
#if ! defined(TS_CLASS) && (defined(COROSYNC_BSD) || defined(COROSYNC_LINUX) || defined(COROSYNC_SOLARIS))
- struct sched_param sched_param;
int res;
sched_priority = sched_get_priority_max (SCHED_RR);
if (sched_priority != -1) {
- sched_param.sched_priority = sched_priority;
- res = sched_setscheduler (0, SCHED_RR, &sched_param);
+ global_sched_param.sched_priority = sched_priority;
+ res = sched_setscheduler (0, SCHED_RR, &global_sched_param);
if (res == -1) {
log_printf (LOGSYS_LEVEL_WARNING, "Could not set SCHED_RR at priority %d: %s\n",
- sched_param.sched_priority, strerror (errno));
+ global_sched_param.sched_priority, strerror (errno));
}
} else {
log_printf (LOGSYS_LEVEL_WARNING, "Could not get maximum scheduler priority: %s\n", strerror (errno));
@@ -733,6 +734,17 @@
if (background)
corosync_tty_detach ();
+ /*
+ * Set round robin realtime scheduling with priority 99
+ * Lock all memory to avoid page faults which may interrupt
+ * application healthchecking
+ */
+ if (setprio) {
+ corosync_setscheduler ();
+ }
+
+ corosync_mlockall ();
+
log_printf (LOGSYS_LEVEL_NOTICE, "Corosync Executive Service RELEASE '%s'\n", RELEASE_VERSION);
log_printf (LOGSYS_LEVEL_NOTICE, "Copyright (C) 2002-2006 MontaVista Software, Inc and contributors.\n");
log_printf (LOGSYS_LEVEL_NOTICE, "Copyright (C) 2006-2008 Red Hat, Inc.\n");
@@ -839,6 +851,15 @@
syslog (LOGSYS_LEVEL_ERROR, "%s", error_string);
corosync_exit_error (AIS_DONE_MAINCONFIGREAD);
}
+ logsys_fork_completed();
+ if (setprio) {
+ res = logsys_thread_priority_set (SCHED_RR, &global_sched_param);
+ if (res == -1) {
+ log_printf (LOGSYS_LEVEL_ERROR,
+ "Could not set logsys thread priority. Can't continue because of priority inversions.");
+ corosync_exit_error (AIS_DONE_LOGSETUP);
+ }
+ }
res = totem_config_read (objdb, &totem_config, &error_string);
if (res == -1) {
@@ -858,16 +879,6 @@
corosync_exit_error (AIS_DONE_MAINCONFIGREAD);
}
- /*
- * Set round robin realtime scheduling with priority 99
- * Lock all memory to avoid page faults which may interrupt
- * application healthchecking
- */
- if (setprio)
- corosync_setscheduler ();
-
- corosync_mlockall ();
-
totem_config.totem_logging_configuration = totem_logging_configuration;
totem_config.totem_logging_configuration.log_subsys_id =
_logsys_subsys_create ("TOTEM");
_______________________________________________
Openais mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/openais