diff --git a/include/haproxy/stick_table.h b/include/haproxy/stick_table.h index 3ca08f0c2..32475a479 100644 --- a/include/haproxy/stick_table.h +++ b/include/haproxy/stick_table.h @@ -203,4 +203,130 @@ static inline void stkctr_clr_flags(struct stkctr *stkctr, unsigned int flags) stkctr->entry = caddr_clr_flags(stkctr->entry, flags); } +/* Increase the number of cumulated HTTP requests in the tracked counter + * . It returns 0 if the entry pointer does not exist and nothing is + * performed. Otherwise it returns 1. + */ +static inline int stkctr_inc_http_req_ctr(struct stkctr *stkctr) +{ + 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_HTTP_REQ_CNT); + if (ptr1) + stktable_data_cast(ptr1, http_req_cnt)++; + + ptr2 = stktable_data_ptr(stkctr->table, ts, STKTABLE_DT_HTTP_REQ_RATE); + if (ptr2) + update_freq_ctr_period(&stktable_data_cast(ptr2, http_req_rate), + stkctr->table->data_arg[STKTABLE_DT_HTTP_REQ_RATE].u, 1); + + 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; +} + +/* Increase the number of cumulated failed HTTP requests in the tracked counter + * . It returns 0 if the entry pointer does not exist and nothing is + * performed. Otherwise it returns 1. + */ +static inline int stkctr_inc_http_err_ctr(struct stkctr *stkctr) +{ + 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_HTTP_ERR_CNT); + if (ptr1) + stktable_data_cast(ptr1, http_err_cnt)++; + + ptr2 = stktable_data_ptr(stkctr->table, ts, STKTABLE_DT_HTTP_ERR_RATE); + if (ptr2) + update_freq_ctr_period(&stktable_data_cast(ptr2, http_err_rate), + stkctr->table->data_arg[STKTABLE_DT_HTTP_ERR_RATE].u, 1); + + 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; +} + +/* Increase the number of bytes received in the tracked counter . It + * returns 0 if the entry pointer does not exist and nothing is + * performed. Otherwise it returns 1. + */ +static inline int stkctr_inc_bytes_in_ctr(struct stkctr *stkctr, unsigned long long bytes) +{ + 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_BYTES_IN_CNT); + if (ptr1) + stktable_data_cast(ptr1, bytes_in_cnt) += bytes; + + ptr2 = stktable_data_ptr(stkctr->table, ts, STKTABLE_DT_BYTES_IN_RATE); + if (ptr2) + update_freq_ctr_period(&stktable_data_cast(ptr2, bytes_in_rate), + stkctr->table->data_arg[STKTABLE_DT_BYTES_IN_RATE].u, bytes); + 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; +} + +/* Increase the number of bytes sent in the tracked counter . It + * returns 0 if the entry pointer does not exist and nothing is + * performed. Otherwise it returns 1. + */ +static inline int stkctr_inc_bytes_out_ctr(struct stkctr *stkctr, unsigned long long bytes) +{ + 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_BYTES_OUT_CNT); + if (ptr1) + stktable_data_cast(ptr1, bytes_out_cnt) += bytes; + + ptr2 = stktable_data_ptr(stkctr->table, ts, STKTABLE_DT_BYTES_OUT_RATE); + if (ptr2) + update_freq_ctr_period(&stktable_data_cast(ptr2, bytes_out_rate), + stkctr->table->data_arg[STKTABLE_DT_BYTES_OUT_RATE].u, bytes); + 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 */ diff --git a/include/haproxy/stream.h b/include/haproxy/stream.h index e5c9c2937..766740c62 100644 --- a/include/haproxy/stream.h +++ b/include/haproxy/stream.h @@ -230,36 +230,11 @@ static inline void stream_track_stkctr(struct stkctr *ctr, struct stktable *t, s /* Increase the number of cumulated HTTP requests in the tracked counters */ static inline void stream_inc_http_req_ctr(struct stream *s) { - struct stksess *ts; - void *ptr; int i; for (i = 0; i < MAX_SESS_STKCTR; i++) { - struct stkctr *stkctr = &s->stkctr[i]; - - ts = stkctr_entry(stkctr); - if (!ts) { - stkctr = &s->sess->stkctr[i]; - ts = stkctr_entry(stkctr); - if (!ts) - continue; - } - - HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &ts->lock); - - ptr = stktable_data_ptr(stkctr->table, ts, STKTABLE_DT_HTTP_REQ_CNT); - if (ptr) - stktable_data_cast(ptr, http_req_cnt)++; - - ptr = stktable_data_ptr(stkctr->table, ts, STKTABLE_DT_HTTP_REQ_RATE); - if (ptr) - update_freq_ctr_period(&stktable_data_cast(ptr, http_req_rate), - stkctr->table->data_arg[STKTABLE_DT_HTTP_REQ_RATE].u, 1); - - HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock); - - /* If data was modified, we need to touch to re-schedule sync */ - stktable_touch_local(stkctr->table, ts, 0); + if (!stkctr_inc_http_req_ctr(&s->stkctr[i])) + stkctr_inc_http_req_ctr(&s->sess->stkctr[i]); } } @@ -268,35 +243,13 @@ static inline void stream_inc_http_req_ctr(struct stream *s) */ static inline void stream_inc_be_http_req_ctr(struct stream *s) { - struct stksess *ts; - void *ptr; int i; for (i = 0; i < MAX_SESS_STKCTR; i++) { - struct stkctr *stkctr = &s->stkctr[i]; - - ts = stkctr_entry(stkctr); - if (!ts) + if (!stkctr_entry(&s->stkctr[i]) || !(stkctr_flags(&s->stkctr[i]) & STKCTR_TRACK_BACKEND)) continue; - if (!(stkctr_flags(&s->stkctr[i]) & STKCTR_TRACK_BACKEND)) - continue; - - HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &ts->lock); - - ptr = stktable_data_ptr(stkctr->table, ts, STKTABLE_DT_HTTP_REQ_CNT); - if (ptr) - stktable_data_cast(ptr, http_req_cnt)++; - - ptr = stktable_data_ptr(stkctr->table, ts, STKTABLE_DT_HTTP_REQ_RATE); - if (ptr) - update_freq_ctr_period(&stktable_data_cast(ptr, http_req_rate), - stkctr->table->data_arg[STKTABLE_DT_HTTP_REQ_RATE].u, 1); - - HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock); - - /* If data was modified, we need to touch to re-schedule sync */ - stktable_touch_local(stkctr->table, ts, 0); + stkctr_inc_http_req_ctr(&s->stkctr[i]); } } @@ -308,36 +261,11 @@ static inline void stream_inc_be_http_req_ctr(struct stream *s) */ static inline void stream_inc_http_err_ctr(struct stream *s) { - struct stksess *ts; - void *ptr; int i; for (i = 0; i < MAX_SESS_STKCTR; i++) { - struct stkctr *stkctr = &s->stkctr[i]; - - ts = stkctr_entry(stkctr); - if (!ts) { - stkctr = &s->sess->stkctr[i]; - ts = stkctr_entry(stkctr); - if (!ts) - continue; - } - - HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &ts->lock); - - ptr = stktable_data_ptr(stkctr->table, ts, STKTABLE_DT_HTTP_ERR_CNT); - if (ptr) - stktable_data_cast(ptr, http_err_cnt)++; - - ptr = stktable_data_ptr(stkctr->table, ts, STKTABLE_DT_HTTP_ERR_RATE); - if (ptr) - update_freq_ctr_period(&stktable_data_cast(ptr, http_err_rate), - stkctr->table->data_arg[STKTABLE_DT_HTTP_ERR_RATE].u, 1); - - HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock); - - /* If data was modified, we need to touch to re-schedule sync */ - stktable_touch_local(stkctr->table, ts, 0); + if (!stkctr_inc_http_err_ctr(&s->stkctr[i])) + stkctr_inc_http_err_ctr(&s->sess->stkctr[i]); } } diff --git a/src/stream.c b/src/stream.c index 0ca54afe0..d121fbe7b 100644 --- a/src/stream.c +++ b/src/stream.c @@ -757,8 +757,6 @@ void stream_process_counters(struct stream *s) { struct session *sess = s->sess; unsigned long long bytes; - void *ptr1,*ptr2; - struct stksess *ts; int i; bytes = s->req.total - s->logs.bytes_in; @@ -774,30 +772,8 @@ void stream_process_counters(struct stream *s) _HA_ATOMIC_ADD(&sess->listener->counters->bytes_in, bytes); for (i = 0; i < MAX_SESS_STKCTR; i++) { - struct stkctr *stkctr = &s->stkctr[i]; - - ts = stkctr_entry(stkctr); - if (!ts) { - stkctr = &sess->stkctr[i]; - ts = stkctr_entry(stkctr); - if (!ts) - continue; - } - - HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &ts->lock); - ptr1 = stktable_data_ptr(stkctr->table, ts, STKTABLE_DT_BYTES_IN_CNT); - if (ptr1) - stktable_data_cast(ptr1, bytes_in_cnt) += bytes; - - ptr2 = stktable_data_ptr(stkctr->table, ts, STKTABLE_DT_BYTES_IN_RATE); - if (ptr2) - update_freq_ctr_period(&stktable_data_cast(ptr2, bytes_in_rate), - stkctr->table->data_arg[STKTABLE_DT_BYTES_IN_RATE].u, bytes); - 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); + if (!stkctr_inc_bytes_in_ctr(&s->stkctr[i], bytes)) + stkctr_inc_bytes_in_ctr(&sess->stkctr[i], bytes); } } @@ -814,30 +790,8 @@ void stream_process_counters(struct stream *s) _HA_ATOMIC_ADD(&sess->listener->counters->bytes_out, bytes); for (i = 0; i < MAX_SESS_STKCTR; i++) { - struct stkctr *stkctr = &s->stkctr[i]; - - ts = stkctr_entry(stkctr); - if (!ts) { - stkctr = &sess->stkctr[i]; - ts = stkctr_entry(stkctr); - if (!ts) - continue; - } - - HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &ts->lock); - ptr1 = stktable_data_ptr(stkctr->table, ts, STKTABLE_DT_BYTES_OUT_CNT); - if (ptr1) - stktable_data_cast(ptr1, bytes_out_cnt) += bytes; - - ptr2 = stktable_data_ptr(stkctr->table, ts, STKTABLE_DT_BYTES_OUT_RATE); - if (ptr2) - update_freq_ctr_period(&stktable_data_cast(ptr2, bytes_out_rate), - stkctr->table->data_arg[STKTABLE_DT_BYTES_OUT_RATE].u, bytes); - 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, stkctr_entry(stkctr), 0); + if (!stkctr_inc_bytes_out_ctr(&s->stkctr[i], bytes)) + stkctr_inc_bytes_out_ctr(&sess->stkctr[i], bytes); } } }