You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by yl...@apache.org on 2019/03/12 10:45:02 UTC

svn commit: r1855306 - in /httpd/httpd/trunk: CHANGES include/scoreboard.h server/mpm/event/event.c server/mpm/motorz/motorz.c server/mpm/prefork/prefork.c server/mpm/worker/worker.c

Author: ylavic
Date: Tue Mar 12 10:45:02 2019
New Revision: 1855306

URL: http://svn.apache.org/viewvc?rev=1855306&view=rev
Log:
MPMs unix: bind the bucket number of each child to its slot number

We need not remember each child's bucket number in SHM for restarts, for the
lifetime of the httpd main process the bucket number can be bound to the slot
number such that: bucket = slot % num_buckets.

This both simplifies the logic and helps children maintenance per bucket in
threaded MPMs, where previously perform_idle_server_maintenance() could create
or kill children processes for the buckets it was not in charge of.

Modified:
    httpd/httpd/trunk/CHANGES
    httpd/httpd/trunk/include/scoreboard.h
    httpd/httpd/trunk/server/mpm/event/event.c
    httpd/httpd/trunk/server/mpm/motorz/motorz.c
    httpd/httpd/trunk/server/mpm/prefork/prefork.c
    httpd/httpd/trunk/server/mpm/worker/worker.c

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1855306&r1=1855305&r2=1855306&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Tue Mar 12 10:45:02 2019
@@ -1,6 +1,9 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.1
 
+  *) MPMs unix: bind the bucket number of each child to its slot number, for a
+     more efficient per bucket maintenance. [Yann Ylavic]
+
   *) mod_http2: when SSL renegotiation is inhibited and a 403 ErrorDocument is
      in play, the proper HTTP/2 stream reset did not trigger with H2_ERR_HTTP_1_1_REQUIRED.
      Fixed. [Michael Kaufmann] 

Modified: httpd/httpd/trunk/include/scoreboard.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/scoreboard.h?rev=1855306&r1=1855305&r2=1855306&view=diff
==============================================================================
--- httpd/httpd/trunk/include/scoreboard.h (original)
+++ httpd/httpd/trunk/include/scoreboard.h Tue Mar 12 10:45:02 2019
@@ -148,7 +148,10 @@ struct process_score {
     apr_uint32_t lingering_close;   /* async connections in lingering close */
     apr_uint32_t keep_alive;        /* async connections in keep alive */
     apr_uint32_t suspended;         /* connections suspended by some module */
-    int bucket;             /* Listener bucket used by this child */
+    int bucket;  /* Listener bucket used by this child; this field is DEPRECATED
+                  * and no longer updated by the MPMs (i.e. always zero) from
+                  * 2.5.x and later.
+                  */
 };
 
 /* Scoreboard is now in 'local' memory, since it isn't updated once created,

Modified: httpd/httpd/trunk/server/mpm/event/event.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/mpm/event/event.c?rev=1855306&r1=1855305&r2=1855306&view=diff
==============================================================================
--- httpd/httpd/trunk/server/mpm/event/event.c (original)
+++ httpd/httpd/trunk/server/mpm/event/event.c Tue Mar 12 10:45:02 2019
@@ -2977,7 +2977,6 @@ static int make_child(server_rec * s, in
 
     ap_scoreboard_image->parent[slot].quiescing = 0;
     ap_scoreboard_image->parent[slot].not_accepting = 0;
-    ap_scoreboard_image->parent[slot].bucket = bucket;
     event_note_child_started(slot, pid);
     active_daemons++;
     retained->total_daemons++;
@@ -3016,6 +3015,7 @@ static void perform_idle_server_maintena
          * that threads_per_child is always > 0 */
         int status = SERVER_DEAD;
         int child_threads_active = 0;
+        int bucket = i % num_buckets;
 
         if (i >= retained->max_daemons_limit &&
             free_length == retained->idle_spawn_rate[child_bucket]) {
@@ -3039,7 +3039,7 @@ static void perform_idle_server_maintena
                  */
                 if (status <= SERVER_READY && !ps->quiescing && !ps->not_accepting
                     && ps->generation == retained->mpm->my_generation
-                    && ps->bucket == child_bucket)
+                    && bucket == child_bucket)
                 {
                     ++idle_thread_count;
                 }
@@ -3050,7 +3050,9 @@ static void perform_idle_server_maintena
             last_non_dead = i;
         }
         active_thread_count += child_threads_active;
-        if (!ps->pid && free_length < retained->idle_spawn_rate[child_bucket])
+        if (!ps->pid
+                && bucket == child_bucket
+                && free_length < retained->idle_spawn_rate[child_bucket])
             free_slots[free_length++] = i;
         else if (child_threads_active == threads_per_child)
             had_healthy_child = 1;
@@ -3243,13 +3245,14 @@ static void server_main_loop(int remaini
                 retained->total_daemons--;
                 if (processed_status == APEXIT_CHILDSICK) {
                     /* resource shortage, minimize the fork rate */
-                    retained->idle_spawn_rate[ps->bucket] = 1;
+                    retained->idle_spawn_rate[child_slot % num_buckets] = 1;
                 }
                 else if (remaining_children_to_start) {
                     /* we're still doing a 1-for-1 replacement of dead
                      * children with new children
                      */
-                    make_child(ap_server_conf, child_slot, ps->bucket);
+                    make_child(ap_server_conf, child_slot,
+                               child_slot % num_buckets);
                     --remaining_children_to_start;
                 }
             }

Modified: httpd/httpd/trunk/server/mpm/motorz/motorz.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/mpm/motorz/motorz.c?rev=1855306&r1=1855305&r2=1855306&view=diff
==============================================================================
--- httpd/httpd/trunk/server/mpm/motorz/motorz.c (original)
+++ httpd/httpd/trunk/server/mpm/motorz/motorz.c Tue Mar 12 10:45:02 2019
@@ -948,8 +948,9 @@ static void child_main(motorz_core_t *mz
     clean_child_exit(0);
 }
 
-static int make_child(motorz_core_t *mz, server_rec *s, int slot, int bucket)
+static int make_child(motorz_core_t *mz, server_rec *s, int slot)
 {
+    int bucket = slot % mz->mpm->num_buckets;
     int pid;
 
     if (slot + 1 > mz->max_daemons_limit) {
@@ -1020,7 +1021,6 @@ static int make_child(motorz_core_t *mz,
         child_main(mz, slot, bucket);
     }
 
-    ap_scoreboard_image->parent[slot].bucket = bucket;
     motorz_note_child_started(mz, slot, pid);
 
     return 0;
@@ -1036,7 +1036,7 @@ static void startup_children(motorz_core
         if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) {
             continue;
         }
-        if (make_child(mz, ap_server_conf, i, i % mz->mpm->num_buckets) < 0) {
+        if (make_child(mz, ap_server_conf, i) < 0) {
             break;
         }
         --number_to_start;
@@ -1045,8 +1045,6 @@ static void startup_children(motorz_core
 
 static void perform_idle_server_maintenance(motorz_core_t *mz, apr_pool_t *p)
 {
-    static int bucket_make_child_record = -1;
-    static int bucket_kill_child_record = -1;
     int free_length;
     int free_slots[1];
 
@@ -1070,6 +1068,7 @@ static void perform_idle_server_maintena
         }
     }
     if (active > ap_num_kids) {
+        static int bucket_kill_child_record = -1;
         /* kill off one child... we use the pod because that'll cause it to
          * shut down gracefully, in case it happened to pick up a request
          * while we were counting
@@ -1078,10 +1077,7 @@ static void perform_idle_server_maintena
         ap_mpm_pod_signal(all_buckets[bucket_kill_child_record].pod);
     }
     else if (active < ap_num_kids) {
-        bucket_make_child_record++;
-        bucket_make_child_record %= mz->mpm->num_buckets;
-        make_child(mz, ap_server_conf, free_slots[0],
-                   bucket_make_child_record);
+        make_child(mz, ap_server_conf, free_slots[0]);
     }
 }
 
@@ -1113,7 +1109,7 @@ static int motorz_run(apr_pool_t *_pconf
 
     if (one_process) {
         AP_MONCONTROL(1);
-        make_child(mz, ap_server_conf, 0, 0);
+        make_child(mz, ap_server_conf, 0);
         /* NOTREACHED */
         ap_assert(0);
         return !OK;
@@ -1201,8 +1197,7 @@ static int motorz_run(apr_pool_t *_pconf
                     /* we're still doing a 1-for-1 replacement of dead
                      * children with new children
                      */
-                    make_child(mz, ap_server_conf, child_slot,
-                               ap_get_scoreboard_process(child_slot)->bucket);
+                    make_child(mz, ap_server_conf, child_slot);
                     --remaining_children_to_start;
                 }
 #if APR_HAS_OTHER_CHILD

Modified: httpd/httpd/trunk/server/mpm/prefork/prefork.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/mpm/prefork/prefork.c?rev=1855306&r1=1855305&r2=1855306&view=diff
==============================================================================
--- httpd/httpd/trunk/server/mpm/prefork/prefork.c (original)
+++ httpd/httpd/trunk/server/mpm/prefork/prefork.c Tue Mar 12 10:45:02 2019
@@ -643,8 +643,9 @@ static void child_main(int child_num_arg
 }
 
 
-static int make_child(server_rec *s, int slot, int bucket)
+static int make_child(server_rec *s, int slot)
 {
+    int bucket = slot % retained->mpm->num_buckets;
     int pid;
 
     if (slot + 1 > retained->max_daemons_limit) {
@@ -722,7 +723,6 @@ static int make_child(server_rec *s, int
         child_main(slot, bucket);
     }
 
-    ap_scoreboard_image->parent[slot].bucket = bucket;
     prefork_note_child_started(slot, pid);
 
     return 0;
@@ -738,7 +738,7 @@ static void startup_children(int number_
         if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) {
             continue;
         }
-        if (make_child(ap_server_conf, i, i % retained->mpm->num_buckets) < 0) {
+        if (make_child(ap_server_conf, i) < 0) {
             break;
         }
         --number_to_start;
@@ -747,8 +747,6 @@ static void startup_children(int number_
 
 static void perform_idle_server_maintenance(apr_pool_t *p)
 {
-    static int bucket_make_child_record = -1;
-    static int bucket_kill_child_record = -1;
     int i;
     int idle_count;
     worker_score *ws;
@@ -795,6 +793,7 @@ static void perform_idle_server_maintena
     }
     retained->max_daemons_limit = last_non_dead + 1;
     if (idle_count > ap_daemons_max_free) {
+        static int bucket_kill_child_record = -1;
         /* kill off one child... we use the pod because that'll cause it to
          * shut down gracefully, in case it happened to pick up a request
          * while we were counting
@@ -825,10 +824,7 @@ static void perform_idle_server_maintena
                     idle_count, total_non_dead);
             }
             for (i = 0; i < free_length; ++i) {
-                bucket_make_child_record++;
-                bucket_make_child_record %= retained->mpm->num_buckets;
-                make_child(ap_server_conf, free_slots[i],
-                           bucket_make_child_record);
+                make_child(ap_server_conf, free_slots[i]);
             }
             /* the next time around we want to spawn twice as many if this
              * wasn't good enough, but not if we've just done a graceful
@@ -873,7 +869,7 @@ static int prefork_run(apr_pool_t *_pcon
 
     if (one_process) {
         AP_MONCONTROL(1);
-        make_child(ap_server_conf, 0, 0);
+        make_child(ap_server_conf, 0);
         /* NOTREACHED */
         ap_assert(0);
         return !OK;
@@ -982,8 +978,7 @@ static int prefork_run(apr_pool_t *_pcon
                     /* we're still doing a 1-for-1 replacement of dead
                      * children with new children
                      */
-                    make_child(ap_server_conf, child_slot,
-                               ap_get_scoreboard_process(child_slot)->bucket);
+                    make_child(ap_server_conf, child_slot);
                     --remaining_children_to_start;
                 }
 #if APR_HAS_OTHER_CHILD

Modified: httpd/httpd/trunk/server/mpm/worker/worker.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/mpm/worker/worker.c?rev=1855306&r1=1855305&r2=1855306&view=diff
==============================================================================
--- httpd/httpd/trunk/server/mpm/worker/worker.c (original)
+++ httpd/httpd/trunk/server/mpm/worker/worker.c Tue Mar 12 10:45:02 2019
@@ -1344,7 +1344,6 @@ static int make_child(server_rec *s, int
         worker_note_child_lost_slot(slot, pid);
     }
     ap_scoreboard_image->parent[slot].quiescing = 0;
-    ap_scoreboard_image->parent[slot].bucket = bucket;
     worker_note_child_started(slot, pid);
     return 0;
 }
@@ -1393,6 +1392,7 @@ static void perform_idle_server_maintena
         int any_dead_threads = 0;
         int all_dead_threads = 1;
         int child_threads_active = 0;
+        int bucket = i % num_buckets;
 
         if (i >= retained->max_daemons_limit &&
             totally_free_length == retained->idle_spawn_rate[child_bucket]) {
@@ -1425,7 +1425,7 @@ static void perform_idle_server_maintena
                 if (status <= SERVER_READY &&
                         !ps->quiescing &&
                         ps->generation == retained->mpm->my_generation &&
-                        ps->bucket == child_bucket) {
+                        bucket == child_bucket) {
                     ++idle_thread_count;
                 }
                 if (status >= SERVER_READY && status < SERVER_GRACEFUL) {
@@ -1435,6 +1435,7 @@ static void perform_idle_server_maintena
         }
         active_thread_count += child_threads_active;
         if (any_dead_threads
+                && bucket == child_bucket
                 && totally_free_length < retained->idle_spawn_rate[child_bucket]
                 && free_length < MAX_SPAWN_RATE / num_buckets
                 && (!ps->pid               /* no process in the slot */
@@ -1620,14 +1621,15 @@ static void server_main_loop(int remaini
                 ps->quiescing = 0;
                 if (processed_status == APEXIT_CHILDSICK) {
                     /* resource shortage, minimize the fork rate */
-                    retained->idle_spawn_rate[ps->bucket] = 1;
+                    retained->idle_spawn_rate[child_slot % num_buckets] = 1;
                 }
                 else if (remaining_children_to_start
                     && child_slot < ap_daemons_limit) {
                     /* we're still doing a 1-for-1 replacement of dead
                      * children with new children
                      */
-                    make_child(ap_server_conf, child_slot, ps->bucket);
+                    make_child(ap_server_conf, child_slot,
+                               child_slot % num_buckets);
                     --remaining_children_to_start;
                 }
             }