From 1fe43d07989316d308e4dfd6989038fa09a51ff1 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 18 Mar 2013 13:13:35 +0400 Subject: [PATCH] Add oom, wasted, hash and manual restart counters to help identify potential configuration problems --- ext/opcache/ZendAccelerator.c | 34 +++++++++++++++++++++------ ext/opcache/ZendAccelerator.h | 14 ++++++++++- ext/opcache/zend_accelerator_module.c | 14 +++++++---- ext/opcache/zend_shared_alloc.c | 4 ++-- 4 files changed, 52 insertions(+), 14 deletions(-) diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index a85b7e40a6..7c5e124729 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -852,7 +852,7 @@ static void zend_accel_schedule_restart_if_necessary(TSRMLS_D) { if ((((double) ZSMMG(wasted_shared_memory)) / ZCG(accel_directives).memory_consumption) >= ZCG(accel_directives).max_wasted_percentage) { ZSMMG(memory_exhausted) = 1; - zend_accel_schedule_restart(TSRMLS_C); + zend_accel_schedule_restart(ACCEL_RESTART_WASTED TSRMLS_CC); } } @@ -1030,7 +1030,7 @@ static void zend_accel_add_key(char *key, unsigned int key_length, zend_accel_ha if (zend_accel_hash_is_full(&ZCSG(hash))) { zend_accel_error(ACCEL_LOG_DEBUG, "No more entries in hash table!"); ZSMMG(memory_exhausted) = 1; - zend_accel_schedule_restart(TSRMLS_C); + zend_accel_schedule_restart(ACCEL_RESTART_HASH TSRMLS_CC); } else { char *new_key = zend_shared_alloc(key_length + 1); if (new_key) { @@ -1057,7 +1057,7 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr if (zend_accel_hash_is_full(&ZCSG(hash))) { zend_accel_error(ACCEL_LOG_DEBUG, "No more entries in hash table!"); ZSMMG(memory_exhausted) = 1; - zend_accel_schedule_restart(TSRMLS_C); + zend_accel_schedule_restart(ACCEL_RESTART_HASH TSRMLS_CC); zend_shared_alloc_unlock(TSRMLS_C); return new_persistent_script; } @@ -1118,7 +1118,7 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr if (!zend_accel_hash_update(&ZCSG(hash), key, key_length + 1, 1, bucket)) { zend_accel_error(ACCEL_LOG_DEBUG, "No more entries in hash table!"); ZSMMG(memory_exhausted) = 1; - zend_accel_schedule_restart(TSRMLS_C); + zend_accel_schedule_restart(ACCEL_RESTART_HASH TSRMLS_CC); } } @@ -1500,7 +1500,7 @@ static zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int ZCSG(misses)++; /* No memory left. Behave like without the Accelerator */ - if (ZSMMG(memory_exhausted)) { + if (ZSMMG(memory_exhausted) || ZCSG(restart_pending)) { SHM_PROTECT(); return accelerator_orig_compile_file(file_handle, type TSRMLS_CC); } @@ -1964,6 +1964,20 @@ static void accel_activate(void) if (accel_is_inactive(TSRMLS_C) == SUCCESS) { zend_accel_error(ACCEL_LOG_DEBUG, "Restarting!"); ZCSG(restart_pending) = 0; + switch ZCSG(restart_reason) { + case ACCEL_RESTART_OOM: + ZCSG(oom_restarts)++; + break; + case ACCEL_RESTART_WASTED: + ZCSG(wasted_restarts)++; + break; + case ACCEL_RESTART_HASH: + ZCSG(hash_restarts)++; + break; + case ACCEL_RESTART_USER: + ZCSG(manual_restarts)++; + break; + } accel_restart_enter(TSRMLS_C); zend_reset_cache_vars(TSRMLS_C); @@ -2322,8 +2336,13 @@ static void zend_accel_init_shm(TSRMLS_D) zend_reset_cache_vars(TSRMLS_C); + ZCSG(oom_restarts) = 0; + ZCSG(wasted_restarts) = 0; + ZCSG(hash_restarts) = 0; + ZCSG(manual_restarts) = 0; + ZCSG(accelerator_enabled) = 1; - ZCSG(last_restart_time) = 0; + ZCSG(last_restart_time) = zend_accel_get_time(); ZCSG(restart_in_progress) = 0; zend_shared_alloc_unlock(TSRMLS_C); @@ -2547,7 +2566,7 @@ static void accel_shutdown(zend_extension *extension) } -void zend_accel_schedule_restart(TSRMLS_D) +void zend_accel_schedule_restart(zend_accel_restart_reason reason TSRMLS_DC) { if (ZCSG(restart_pending)) { /* don't schedule twice */ @@ -2556,6 +2575,7 @@ void zend_accel_schedule_restart(TSRMLS_D) zend_accel_error(ACCEL_LOG_DEBUG, "Restart Scheduled!"); ZCSG(restart_pending) = 1; + ZCSG(restart_reason) = reason; ZCSG(cache_status_before_restart) = ZCSG(accelerator_enabled); ZCSG(accelerator_enabled) = 0; diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h index be2218cdb8..45eae71dd7 100644 --- a/ext/opcache/ZendAccelerator.h +++ b/ext/opcache/ZendAccelerator.h @@ -164,6 +164,13 @@ typedef unsigned __int64 accel_time_t; typedef time_t accel_time_t; #endif +typedef enum _zend_accel_restart_reason { + ACCEL_RESTART_OOM, /* restart because of out of memory */ + ACCEL_RESTART_WASTED, /* restart because of wasted memory */ + ACCEL_RESTART_HASH, /* restart because of hash overflow */ + ACCEL_RESTART_USER /* restart sheduled by opcache_reset() */ +} zend_accel_restart_reason; + typedef struct _zend_persistent_script { ulong hash_value; char *full_path; /* full real path with resolved symlinks */ @@ -259,6 +266,10 @@ typedef struct _zend_accel_shared_globals { unsigned long hits; unsigned long misses; unsigned long blacklist_misses; + unsigned long oom_restarts; /* number of restarts because of out of memory */ + unsigned long wasted_restarts; /* number of restarts because of wasted memory */ + unsigned long hash_restarts; /* number of restarts because of hash overflow */ + unsigned long manual_restarts; /* number of restarts sheduled by opcache_reset() */ zend_accel_hash hash; /* hash table for cached scripts */ zend_accel_hash include_paths; /* used "include_path" values */ @@ -267,6 +278,7 @@ typedef struct _zend_accel_shared_globals { time_t force_restart_time; zend_bool accelerator_enabled; zend_bool restart_pending; + zend_accel_restart_reason restart_reason; zend_bool cache_status_before_restart; #ifdef ZEND_WIN32 unsigned long mem_usage; @@ -304,7 +316,7 @@ extern zend_accel_globals accel_globals; extern char *zps_api_failure_reason; -void zend_accel_schedule_restart(TSRMLS_D); +void zend_accel_schedule_restart(zend_accel_restart_reason reason TSRMLS_DC); int accelerator_shm_read_lock(TSRMLS_D); void accelerator_shm_read_unlock(TSRMLS_D); diff --git a/ext/opcache/zend_accelerator_module.c b/ext/opcache/zend_accelerator_module.c index 50596aaf08..019ce6697e 100644 --- a/ext/opcache/zend_accelerator_module.c +++ b/ext/opcache/zend_accelerator_module.c @@ -342,7 +342,7 @@ void zend_accel_info(ZEND_MODULE_INFO_FUNC_ARGS) { php_info_print_table_start(); - if (ZCG(enabled) && accel_startup_ok && ZCSG(accelerator_enabled)) { + if (ZCG(enabled) && accel_startup_ok && (ZCG(counted) || ZCSG(accelerator_enabled))) { php_info_print_table_row(2, "Opcode Caching", "Up and Running"); } else { php_info_print_table_row(2, "Opcode Caching", "Disabled"); @@ -452,8 +452,10 @@ static ZEND_FUNCTION(opcache_get_status) array_init(return_value); /* Trivia */ - add_assoc_bool(return_value, "opcache_enabled", ZCG(enabled) && ZCSG(accelerator_enabled)); + add_assoc_bool(return_value, "opcache_enabled", ZCG(enabled) && (ZCG(counted) || ZCSG(accelerator_enabled))); add_assoc_bool(return_value, "cache_full", ZSMMG(memory_exhausted)); + add_assoc_bool(return_value, "restart_pending", ZCSG(restart_pending)); + add_assoc_bool(return_value, "restart_in_progress", ZCSG(restart_in_progress)); /* Memory usage statistics */ MAKE_STD_ZVAL(memory_usage); @@ -472,6 +474,10 @@ static ZEND_FUNCTION(opcache_get_status) add_assoc_long(statistics, "max_cached_keys", ZCSG(hash).max_num_entries); add_assoc_long(statistics, "hits", ZCSG(hits)); add_assoc_long(statistics, "last_restart_time", ZCSG(last_restart_time)); + add_assoc_long(statistics, "oom_restarts", ZCSG(oom_restarts)); + add_assoc_long(statistics, "wasted_restarts", ZCSG(wasted_restarts)); + add_assoc_long(statistics, "hash_restarts", ZCSG(hash_restarts)); + add_assoc_long(statistics, "manual_restarts", ZCSG(manual_restarts)); add_assoc_long(statistics, "misses", ZSMMG(memory_exhausted)?ZCSG(misses):ZCSG(misses)-ZCSG(blacklist_misses)); add_assoc_long(statistics, "blacklist_misses", ZCSG(blacklist_misses)); reqs = ZCSG(hits)+ZCSG(misses); @@ -561,7 +567,7 @@ static ZEND_FUNCTION(opcache_get_configuration) } /* {{{ proto void accelerator_reset() - Request that the contents of the Accelerator module in the ZPS be reset */ + Request that the contents of the opcode cache to be reset */ static ZEND_FUNCTION(opcache_reset) { /* keep the compiler happy */ @@ -577,6 +583,6 @@ static ZEND_FUNCTION(opcache_reset) RETURN_FALSE; } - zend_accel_schedule_restart(TSRMLS_C); + zend_accel_schedule_restart(ACCEL_RESTART_USER TSRMLS_CC); RETURN_TRUE; } diff --git a/ext/opcache/zend_shared_alloc.c b/ext/opcache/zend_shared_alloc.c index 1a983aeea7..5e37e38586 100644 --- a/ext/opcache/zend_shared_alloc.c +++ b/ext/opcache/zend_shared_alloc.c @@ -276,8 +276,8 @@ static size_t zend_shared_alloc_get_largest_free_block(void) #define SHARED_ALLOC_FAILED() do { \ zend_accel_error(ACCEL_LOG_WARNING, "Not enough free shared space to allocate %ld bytes (%ld bytes free)", (long)size, (long)ZSMMG(shared_free)); \ if (zend_shared_alloc_get_largest_free_block() < MIN_FREE_MEMORY) { \ - ZSMMG(memory_exhausted) = 1; \ - zend_accel_schedule_restart(TSRMLS_C); \ + ZSMMG(memory_exhausted) = 1; \ + zend_accel_schedule_restart(ACCEL_RESTART_OOM TSRMLS_CC); \ } \ } while (0) -- 2.40.0