diff options
Diffstat (limited to 'include/haproxy/stick_table.h')
-rw-r--r-- | include/haproxy/stick_table.h | 63 |
1 files changed, 61 insertions, 2 deletions
diff --git a/include/haproxy/stick_table.h b/include/haproxy/stick_table.h index 3200437..2c5e7a2 100644 --- a/include/haproxy/stick_table.h +++ b/include/haproxy/stick_table.h @@ -29,7 +29,9 @@ #include <haproxy/freq_ctr.h> #include <haproxy/sample-t.h> #include <haproxy/stick_table-t.h> +#include <haproxy/thread.h> #include <haproxy/ticks.h> +#include <haproxy/xxhash.h> extern struct stktable *stktables_list; extern struct pool_head *pool_head_stk_ctr; @@ -191,6 +193,19 @@ static inline void *stktable_data_ptr_idx(struct stktable *t, struct stksess *ts return __stktable_data_ptr(t, ts, type) + idx*stktable_type_size(stktable_data_types[type].std_type); } +/* return a shard number for key <key> of len <len> present in table <t>, for + * use with the tree indexing. The value will be from 0 to + * CONFIG_HAP_TBL_BUCKETS-1. + */ +static inline uint stktable_calc_shard_num(const struct stktable *t, const void *key, size_t len) +{ +#if CONFIG_HAP_TBL_BUCKETS > 1 + return XXH32(key, len, t->hash_seed) % CONFIG_HAP_TBL_BUCKETS; +#else + return 0; +#endif +} + /* kill an entry if it's expired and its ref_cnt is zero */ static inline int __stksess_kill_if_expired(struct stktable *t, struct stksess *ts) { @@ -202,14 +217,26 @@ static inline int __stksess_kill_if_expired(struct stktable *t, struct stksess * static inline void stksess_kill_if_expired(struct stktable *t, struct stksess *ts, int decrefcnt) { + uint shard; + size_t len; if (decrefcnt && HA_ATOMIC_SUB_FETCH(&ts->ref_cnt, 1) != 0) return; if (t->expire != TICK_ETERNITY && tick_is_expired(ts->expire, now_ms)) { - HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->lock); + if (t->type == SMP_T_STR) + len = strlen((const char *)ts->key.key); + else + len = t->key_size; + + shard = stktable_calc_shard_num(t, ts->key.key, len); + + /* make the compiler happy when shard is not used without threads */ + ALREADY_CHECKED(shard); + + HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->shards[shard].sh_lock); __stksess_kill_if_expired(t, ts); - HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->lock); + HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->shards[shard].sh_lock); } } @@ -401,4 +428,36 @@ static inline int stkctr_inc_bytes_out_ctr(struct stkctr *stkctr, unsigned long return 1; } +/* Add <inc> to the number of cumulated front glitches in the tracked counter + * <stkctr>. It returns 0 if the entry pointer does not exist and nothing is + * performed. Otherwise it returns 1. + */ +static inline int stkctr_add_glitch_ctr(struct stkctr *stkctr, uint inc) +{ + struct stksess *ts; + void *ptr1, *ptr2; + + ts = stkctr_entry(stkctr); + if (!ts) + return 0; + + HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &ts->lock); + + ptr1 = stktable_data_ptr(stkctr->table, ts, STKTABLE_DT_GLITCH_CNT); + if (ptr1) + stktable_data_cast(ptr1, std_t_uint) += inc; + + ptr2 = stktable_data_ptr(stkctr->table, ts, STKTABLE_DT_GLITCH_RATE); + if (ptr2) + update_freq_ctr_period(&stktable_data_cast(ptr2, std_t_frqp), + stkctr->table->data_arg[STKTABLE_DT_GLITCH_RATE].u, inc); + + HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock); + + /* If data was modified, we need to touch to re-schedule sync */ + if (ptr1 || ptr2) + stktable_touch_local(stkctr->table, ts, 0); + return 1; +} + #endif /* _HAPROXY_STICK_TABLE_H */ |