From 2943e7b89949d2e113945a724dc70e5fef0ee340 Mon Sep 17 00:00:00 2001 From: pjd Date: Thu, 26 Aug 2010 23:33:04 +0000 Subject: - Check the result of malloc(M_NOWAIT) in replay_alloc(). The caller (replay_alloc()) knows how to handle replay_alloc() failure. - Eliminate 'freed_one' variable, it is not needed - when no entry is found rce will be NULL. - Add locking assertions where we expect a rc_lock to be held. Reviewed by: rmacklem MFC after: 2 weeks --- sys/rpc/replay.c | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/sys/rpc/replay.c b/sys/rpc/replay.c index 2e92017..1bd5378 100644 --- a/sys/rpc/replay.c +++ b/sys/rpc/replay.c @@ -113,8 +113,12 @@ replay_alloc(struct replay_cache *rc, { struct replay_cache_entry *rce; + mtx_assert(&rc->rc_lock, MA_OWNED); + rc->rc_count++; rce = malloc(sizeof(*rce), M_RPC, M_NOWAIT|M_ZERO); + if (!rce) + return (NULL); rce->rce_hash = h; rce->rce_msg = *msg; bcopy(addr, &rce->rce_addr, addr->sa_len); @@ -129,6 +133,8 @@ static void replay_free(struct replay_cache *rc, struct replay_cache_entry *rce) { + mtx_assert(&rc->rc_lock, MA_OWNED); + rc->rc_count--; TAILQ_REMOVE(&rc->rc_cache[rce->rce_hash], rce, rce_link); TAILQ_REMOVE(&rc->rc_all, rce, rce_alllink); @@ -143,26 +149,25 @@ static void replay_prune(struct replay_cache *rc) { struct replay_cache_entry *rce; - bool_t freed_one; - - if (rc->rc_count >= REPLAY_MAX || rc->rc_size > rc->rc_maxsize) { - do { - freed_one = FALSE; - /* - * Try to free an entry. Don't free in-progress entries - */ - TAILQ_FOREACH_REVERSE(rce, &rc->rc_all, - replay_cache_list, rce_alllink) { - if (rce->rce_repmsg.rm_xid) { - replay_free(rc, rce); - freed_one = TRUE; - break; - } - } - } while (freed_one - && (rc->rc_count >= REPLAY_MAX - || rc->rc_size > rc->rc_maxsize)); - } + + mtx_assert(&rc->rc_lock, MA_OWNED); + + if (rc->rc_count < REPLAY_MAX && rc->rc_size <= rc->rc_maxsize) + return; + + do { + /* + * Try to free an entry. Don't free in-progress entries. + */ + TAILQ_FOREACH_REVERSE(rce, &rc->rc_all, replay_cache_list, + rce_alllink) { + if (rce->rce_repmsg.rm_xid) + break; + } + if (rce) + replay_free(rc, rce); + } while (rce && (rc->rc_count >= REPLAY_MAX + || rc->rc_size > rc->rc_maxsize)); } enum replay_state -- cgit v1.1