Compare commits

...

3 Commits

Author SHA1 Message Date
Ondřej Surý
71e0de46ef DROPME: PPS logging 2021-06-01 12:59:02 +02:00
Ondřej Surý
fb0ddd440d WIP: log dump begin/end 2021-06-01 12:59:01 +02:00
Ondřej Surý
fe0992f134 Reduce the thread scheduling priority during zone dumping
After the move of the zone dumping process, we can slightly reduce the
scheduling priority of the zone dumping process.  This is either done by
setting the SCHED_BATCH priority at the beginning and SCHED_OTHER (aka
SCHED_NORMAL) back when the zone dumping is done.

(On Windows, this is done by using THREAD_MODE_BACKGROUND_BEGIN and
THREAD_MODE_BACKGROUND_END combo.)

The description (below, from the man page) of SCHED_BATCH talks about
CPU-intensive work which is not the case of the only usage so far, but
we can't use SCHED_IDLE, and the extra penalty in scheduling is what we
need here.

     SCHED_BATCH: Scheduling batch processes

       SCHED_BATCH can be used only at static priority 0.  This policy
       is similar to SCHED_OTHER in that it schedules the thread
       according to its dynamic priority (based on the nice value).  The
       difference is that this policy will cause the scheduler to always
       assume that the thread is CPU-intensive.  Consequently, the
       scheduler will apply a small scheduling penalty with respect to
       wakeup behavior, so that this thread is mildly disfavored in
       scheduling decisions.

       This policy is useful for workloads that are noninteractive, but
       do not want to lower their nice value, and for workloads that
       want a determin‐ istic scheduling policy without interactivity
       causing extra preemptions (between the workload's tasks).

The reason why we can't use SCHED_IDLE is twofold:

1. The rules when we can actually reset the scheduling priority back to
   SCHED_OTHER are complicated:

    * Special rules apply for the SCHED_IDLE policy.  In Linux kernels
      before 2.6.39, an unprivileged thread operating under this policy
      cannot change its policy, regardless of the value of its
      RLIMIT_RTPRIO resource limit.  In Linux kernels since 2.6.39, an
      unprivileged thread can switch to either the SCHED_BATCH or the
      SCHED_OTHER policy so long as its nice value falls within the
      range permitted by its RLIMIT_NICE resource limit (see
      getrlimit(2)).

2. The zone dumping process would become so slow that it won't dump the
   zone in a reasonable amount of time.
2021-06-01 12:03:03 +02:00
6 changed files with 54 additions and 10 deletions

View File

@@ -7402,6 +7402,10 @@ pps_timer_tick(isc_task_t *task, isc_event_t *event) {
*/
dns_pps = (requests - oldrequests) / 1200;
oldrequests = requests;
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR, "PPS: %u",
dns_pps);
}
/*
@@ -9169,7 +9173,7 @@ load_configuration(const char *filename, named_server_t *server,
}
server->heartbeat_interval = heartbeat_interval;
isc_interval_set(&interval, 1200, 0);
isc_interval_set(&interval, 1, 0);
CHECK(isc_timer_reset(server->pps_timer, isc_timertype_ticker, NULL,
&interval, false));

View File

@@ -26,6 +26,7 @@
#include <isc/stdio.h>
#include <isc/string.h>
#include <isc/task.h>
#include <isc/thread.h>
#include <isc/time.h>
#include <isc/types.h>
#include <isc/util.h>
@@ -1495,6 +1496,8 @@ master_dump_cb(void *data) {
dns_dumpctx_t *dctx = data;
REQUIRE(DNS_DCTX_VALID(dctx));
isc_thread_background_begin();
if (atomic_load_acquire(&dctx->canceled)) {
result = ISC_R_CANCELED;
} else {
@@ -1512,6 +1515,8 @@ master_dump_cb(void *data) {
result = flushandsync(dctx->f, result, NULL);
}
isc_thread_background_end();
dctx->result = result;
}
@@ -1739,6 +1744,9 @@ dumptostream(dns_dumpctx_t *dctx) {
dns_fixedname_t fixname;
isc_time_t start;
isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, "dump begin");
bufmem = isc_mem_get(dctx->mctx, initial_buffer_length);
isc_buffer_init(&buffer, bufmem, initial_buffer_length);
@@ -1810,6 +1818,11 @@ dumptostream(dns_dumpctx_t *dctx) {
if (result == ISC_R_NOMORE) {
result = ISC_R_SUCCESS;
}
isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, "dump end: %s",
isc_result_totext(result));
cleanup:
RUNTIME_CHECK(dns_dbiterator_pause(dctx->dbiter) == ISC_R_SUCCESS);
isc_mem_put(dctx->mctx, buffer.base, buffer.length);

View File

@@ -54,4 +54,29 @@ isc_thread_setaffinity(int cpu);
#define isc_thread_self (uintptr_t) pthread_self
/*
* Scheduling priority
*/
#if defined(SCHED_BATCH)
#define isc_thread_background_begin() \
{ \
RUNTIME_CHECK(pthread_setschedparam( \
pthread_self(), SCHED_BATCH, \
&(const struct sched_param){ \
.sched_priority = 0 }) == 0); \
}
#define isc_thread_background_end() \
{ \
RUNTIME_CHECK(pthread_setschedparam( \
pthread_self(), SCHED_OTHER, \
&(const struct sched_param){ \
.sched_priority = 0 }) == 0); \
}
#else
#define isc_thread_background_begin()
#define isc_thread_background_end()
#endif
ISC_LANG_ENDDECLS

View File

@@ -36,6 +36,9 @@
#define THREAD_MINSTACKSIZE (1024U * 1024)
#endif /* ifndef THREAD_MINSTACKSIZE */
thread_local int sched_policy = -1;
thread_local struct sched_param sched_param = { 0 };
#define _FATAL(r, f) \
{ \
char strbuf[ISC_STRERRORSIZE]; \

View File

@@ -33,10 +33,6 @@
typedef uint32_t socklen_t;
#endif
#ifndef thread_local
#define thread_local __declspec(thread)
#endif /* thread_local */
/*
* Limits
*/

View File

@@ -9,8 +9,7 @@
* information regarding copyright ownership.
*/
#ifndef ISC_THREAD_H
#define ISC_THREAD_H 1
#pragma once
#include <inttypes.h>
#include <windows.h>
@@ -18,6 +17,8 @@
#include <isc/lang.h>
#include <isc/result.h>
#define thread_local __declspec(thread)
extern thread_local size_t isc_tid_v;
/*
@@ -90,8 +91,10 @@ isc_thread_setaffinity(int cpu);
#define isc_thread_yield() Sleep(0)
#define thread_local __declspec(thread)
#define isc_thread_background_begin() \
SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_BEGIN)
#define isc_thread_background_end() \
SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_END)
ISC_LANG_ENDDECLS
#endif /* ISC_THREAD_H */