diff options
author | Michael Cahill <michael.cahill@wiredtiger.com> | 2015-02-17 21:56:34 +1100 |
---|---|---|
committer | Michael Cahill <michael.cahill@wiredtiger.com> | 2015-02-17 21:56:34 +1100 |
commit | c34a56f357e21d134a2d9d0fefc032544069d8d7 (patch) | |
tree | d60b5ee0ad538795a25c5d4220813bc19e52f4ea | |
parent | a9de0f7ac8ad373d7aef6a480c69a2a7e0b55c59 (diff) | |
download | mongo-c34a56f357e21d134a2d9d0fefc032544069d8d7.tar.gz |
Allow the maximum number of eviction threads to be reconfigured. This was previously permitted by the API, but the array of thread contexts was not correctly resized, leading to segfaults.
refs SERVER-17293
-rw-r--r-- | src/evict/evict_lru.c | 71 | ||||
-rw-r--r-- | src/include/connection.h | 1 |
2 files changed, 47 insertions, 25 deletions
diff --git a/src/evict/evict_lru.c b/src/evict/evict_lru.c index c6b962f9f5d..6d541e3ffb6 100644 --- a/src/evict/evict_lru.c +++ b/src/evict/evict_lru.c @@ -225,6 +225,47 @@ err: WT_PANIC_MSG(session, ret, "cache eviction server error"); } /* + * __evict_workers_resize -- + * Resize the array of eviction workers (as needed after a reconfigure). + * We don't do this during the reconfigure because the eviction server + * thread owns these structures. + */ +static int +__evict_workers_resize(WT_SESSION_IMPL *session) +{ + WT_CONNECTION_IMPL *conn; + WT_DECL_RET; + WT_EVICT_WORKER *workers; + size_t alloc; + u_int i; + + conn = S2C(session); + + alloc = conn->evict_workers_alloc * sizeof(*workers); + WT_RET(__wt_realloc(session, &alloc, + conn->evict_workers_max * sizeof(*workers), &conn->evict_workctx)); + workers = conn->evict_workctx; + + for (i = conn->evict_workers_alloc; i < conn->evict_workers_max; i++) { + WT_ERR(__wt_open_internal_session(conn, + "eviction-worker", 0, 0, &workers[i].session)); + workers[i].id = i; + F_SET(workers[i].session, WT_SESSION_CAN_WAIT); + + if (i < conn->evict_workers_min) { + ++conn->evict_workers; + F_SET(&workers[i], WT_EVICT_WORKER_RUN); + WT_ERR(__wt_thread_create( + workers[i].session, &workers[i].tid, + __evict_worker, &workers[i])); + } + } + +err: conn->evict_workers_alloc = conn->evict_workers_max; + return (ret); +} + +/* * __wt_evict_create -- * Start the eviction server thread. */ @@ -232,8 +273,6 @@ int __wt_evict_create(WT_SESSION_IMPL *session) { WT_CONNECTION_IMPL *conn; - WT_EVICT_WORKER *workers; - u_int i; conn = S2C(session); @@ -253,27 +292,6 @@ __wt_evict_create(WT_SESSION_IMPL *session) if (conn->evict_workers_max == 0) F_SET(session, WT_SESSION_CAN_WAIT); - if (conn->evict_workers_max > 0) { - WT_RET(__wt_calloc_def( - session, conn->evict_workers_max, &workers)); - conn->evict_workctx = workers; - - for (i = 0; i < conn->evict_workers_max; i++) { - WT_RET(__wt_open_internal_session(conn, - "eviction-worker", 0, 0, &workers[i].session)); - workers[i].id = i; - F_SET(workers[i].session, WT_SESSION_CAN_WAIT); - - if (i < conn->evict_workers_min) { - ++conn->evict_workers; - F_SET(&workers[i], WT_EVICT_WORKER_RUN); - WT_RET(__wt_thread_create( - workers[i].session, &workers[i].tid, - __evict_worker, &workers[i])); - } - } - } - /* * Start the primary eviction server thread after the worker threads * have started to avoid it starting additional worker threads before @@ -314,9 +332,10 @@ __wt_evict_destroy(WT_SESSION_IMPL *session) } /* Handle shutdown when cleaning up after a failed open */ if (conn->evict_workctx != NULL) { - for (i = 0; i < conn->evict_workers_max; i++) { + for (i = 0; i < conn->evict_workers_alloc; i++) { wt_session = &conn->evict_workctx[i].session->iface; - WT_TRET(wt_session->close(wt_session, NULL)); + if (wt_session != NULL) + WT_TRET(wt_session->close(wt_session, NULL)); } __wt_free(session, conn->evict_workctx); } @@ -479,6 +498,8 @@ __evict_pass(WT_SESSION_IMPL *session) WT_RET(__wt_verbose(session, WT_VERB_EVICTSERVER, "Starting evict worker: %"PRIu32"\n", conn->evict_workers)); + if (conn->evict_workers >= conn->evict_workers_alloc) + WT_RET(__evict_workers_resize(session)); worker = &conn->evict_workctx[conn->evict_workers++]; F_SET(worker, WT_EVICT_WORKER_RUN); WT_RET(__wt_thread_create(session, diff --git a/src/include/connection.h b/src/include/connection.h index ff5e401fadd..5e69c93cfce 100644 --- a/src/include/connection.h +++ b/src/include/connection.h @@ -290,6 +290,7 @@ struct __wt_connection_impl { wt_thread_t evict_tid; /* Eviction server thread ID */ int evict_tid_set; /* Eviction server thread ID set */ + uint32_t evict_workers_alloc;/* Allocated eviction workers */ uint32_t evict_workers_max;/* Max eviction workers */ uint32_t evict_workers_min;/* Min eviction workers */ uint32_t evict_workers; /* Number of eviction workers */ |