Use spinlock in host and chart (#15328)
* Switch alarm log lock to spinlock * Switch the alerts lock in the chart structure to spinlock * Proper lock usage
Stelios Fragkakis committed
Jul 10, 2023 at 14:13 UTC
b12edb1208554cdbb93fa3d4e9570bf4a9879e0f
12 files changed
+47
-50
database/contexts/api_v2.c
+4
-4
@@ -408,7 +408,7 @@ static FTS_MATCH rrdcontext_to_json_v2_full_text_search(struct rrdcontext_to_jso
408
409
if(ri->rrdset) {
410
RRDSET *st = ri->rrdset;
411
- netdata_rwlock_rdlock(&st->alerts.rwlock);
411
+ rw_spinlock_read_lock(&st->alerts.spinlock);
412
for (RRDCALC *rcl = st->alerts.base; rcl; rcl = rcl->next) {
413
if(unlikely(full_text_search_string(&ctl->q.fts, q, rcl->name))) {
414
matched = FTS_MATCHED_ALERT;
@@ -420,7 +420,7 @@ static FTS_MATCH rrdcontext_to_json_v2_full_text_search(struct rrdcontext_to_jso
420
break;
421
}
422
}
423
- netdata_rwlock_unlock(&st->alerts.rwlock);
423
+ rw_spinlock_read_unlock(&st->alerts.spinlock);
424
}
425
}
426
dfe_done(ri);
@@ -433,7 +433,7 @@ static bool rrdcontext_matches_alert(struct rrdcontext_to_json_v2_data *ctl, RRD
433
dfe_start_read(rc->rrdinstances, ri) {
434
if(ri->rrdset) {
435
RRDSET *st = ri->rrdset;
436
- netdata_rwlock_rdlock(&st->alerts.rwlock);
436
+ rw_spinlock_read_lock(&st->alerts.spinlock);
437
for (RRDCALC *rcl = st->alerts.base; rcl; rcl = rcl->next) {
438
if(ctl->alerts.alert_name_pattern && !simple_pattern_matches_string(ctl->alerts.alert_name_pattern, rcl->name))
439
continue;
@@ -491,7 +491,7 @@ static bool rrdcontext_matches_alert(struct rrdcontext_to_json_v2_data *ctl, RRD
491
dictionary_set(ctl->alerts.alert_instances, key, &z, sizeof(z));
492
}
493
}
494
- netdata_rwlock_unlock(&st->alerts.rwlock);
494
+ rw_spinlock_read_unlock(&st->alerts.spinlock);
495
}
496
}
497
dfe_done(ri);
database/contexts/query_target.c
+4
-4
@@ -579,7 +579,7 @@ static void query_target_eval_instance_rrdcalc(QUERY_TARGET_LOCALS *qtl __maybe_
579
QUERY_NODE *qn, QUERY_CONTEXT *qc, QUERY_INSTANCE *qi) {
580
RRDSET *st = rrdinstance_acquired_rrdset(qi->ria);
581
if (st) {
582
- netdata_rwlock_rdlock(&st->alerts.rwlock);
582
+ rw_spinlock_read_lock(&st->alerts.spinlock);
583
for (RRDCALC *rc = st->alerts.base; rc; rc = rc->next) {
584
switch(rc->status) {
585
case RRDCALC_STATUS_CLEAR:
@@ -610,7 +610,7 @@ static void query_target_eval_instance_rrdcalc(QUERY_TARGET_LOCALS *qtl __maybe_
610
break;
611
}
612
}
613
- netdata_rwlock_unlock(&st->alerts.rwlock);
613
+ rw_spinlock_read_unlock(&st->alerts.spinlock);
614
}
615
}
616
@@ -624,7 +624,7 @@ static bool query_target_match_alert_pattern(RRDINSTANCE_ACQUIRED *ria, SIMPLE_P
624
625
BUFFER *wb = NULL;
626
bool matched = false;
627
- netdata_rwlock_rdlock(&st->alerts.rwlock);
627
+ rw_spinlock_read_lock(&st->alerts.spinlock);
628
if (st->alerts.base) {
629
for (RRDCALC *rc = st->alerts.base; rc; rc = rc->next) {
630
SIMPLE_PATTERN_RESULT ret = simple_pattern_matches_string_extract(pattern, rc->name, NULL, 0);
@@ -655,7 +655,7 @@ static bool query_target_match_alert_pattern(RRDINSTANCE_ACQUIRED *ria, SIMPLE_P
655
break;
656
}
657
}
658
- netdata_rwlock_unlock(&st->alerts.rwlock);
658
+ rw_spinlock_read_unlock(&st->alerts.spinlock);
659
660
buffer_free(wb);
661
return matched;
database/rrd.h
+2
-2
@@ -886,7 +886,7 @@ struct rrdset {
886
const RRDFAMILY_ACQUIRED *rrdfamily; // pointer to RRDFAMILY dictionary item, this chart belongs to
887
888
struct {
889
- netdata_rwlock_t rwlock; // protection for RRDCALC *base
889
+ RW_SPINLOCK spinlock; // protection for RRDCALC *base
890
RRDCALC *base; // double linked list of RRDCALC related to this RRDSET
891
} alerts;
892
@@ -1106,7 +1106,7 @@ typedef struct alarm_log {
1106
unsigned int count;
1107
unsigned int max;
1108
ALARM_ENTRY *alarms;
1109
- netdata_rwlock_t alarm_log_rwlock;
1109
+ RW_SPINLOCK spinlock;
1110
} ALARM_LOG;
1111
1112
typedef struct health {
database/rrdcalc.c
+8
-8
@@ -62,7 +62,7 @@ inline const char *rrdcalc_status2string(RRDCALC_STATUS status) {
62
}
63
64
uint32_t rrdcalc_get_unique_id(RRDHOST *host, STRING *chart, STRING *name, uint32_t *next_event_id, uuid_t *config_hash_id) {
65
- netdata_rwlock_rdlock(&host->health_log.alarm_log_rwlock);
65
+ rw_spinlock_read_lock(&host->health_log.spinlock);
66
67
// re-use old IDs, by looking them up in the alarm log
68
ALARM_ENTRY *ae = NULL;
@@ -89,7 +89,7 @@ uint32_t rrdcalc_get_unique_id(RRDHOST *host, STRING *chart, STRING *name, uint3
89
}
90
}
91
92
- netdata_rwlock_unlock(&host->health_log.alarm_log_rwlock);
92
+ rw_spinlock_read_unlock(&host->health_log.spinlock);
93
return alarm_id;
94
}
95
@@ -212,9 +212,9 @@ static void rrdcalc_link_to_rrdset(RRDSET *st, RRDCALC *rc) {
212
rc->last_status_change = now_realtime_sec();
213
rc->rrdset = st;
214
215
- netdata_rwlock_wrlock(&st->alerts.rwlock);
215
+ rw_spinlock_write_lock(&st->alerts.spinlock);
216
DOUBLE_LINKED_LIST_APPEND_ITEM_UNSAFE(st->alerts.base, rc, prev, next);
217
- netdata_rwlock_unlock(&st->alerts.rwlock);
217
+ rw_spinlock_write_unlock(&st->alerts.spinlock);
218
219
if(rc->update_every < rc->rrdset->update_every) {
220
netdata_log_error("Health alarm '%s.%s' has update every %d, less than chart update every %d. Setting alarm update frequency to %d.", rrdset_id(rc->rrdset), rrdcalc_name(rc), rc->update_every, rc->rrdset->update_every, rc->rrdset->update_every);
@@ -362,12 +362,12 @@ static void rrdcalc_unlink_from_rrdset(RRDCALC *rc, bool having_ll_wrlock) {
362
// unlink it
363
364
if(!having_ll_wrlock)
365
- netdata_rwlock_wrlock(&st->alerts.rwlock);
365
+ rw_spinlock_write_lock(&st->alerts.spinlock);
366
367
DOUBLE_LINKED_LIST_REMOVE_ITEM_UNSAFE(st->alerts.base, rc, prev, next);
368
369
if(!having_ll_wrlock)
370
- netdata_rwlock_unlock(&st->alerts.rwlock);
370
+ rw_spinlock_write_unlock(&st->alerts.spinlock);
371
372
rc->rrdset = NULL;
373
@@ -808,7 +808,7 @@ void rrdcalc_delete_alerts_not_matching_host_labels_from_all_hosts() {
808
809
void rrdcalc_unlink_all_rrdset_alerts(RRDSET *st) {
810
RRDCALC *rc, *last = NULL;
811
- netdata_rwlock_wrlock(&st->alerts.rwlock);
811
+ rw_spinlock_write_lock(&st->alerts.spinlock);
812
while((rc = st->alerts.base)) {
813
if(last == rc) {
814
netdata_log_error("RRDCALC: malformed list of alerts linked to chart - cannot cleanup - giving up.");
@@ -827,7 +827,7 @@ void rrdcalc_unlink_all_rrdset_alerts(RRDSET *st) {
827
}
828
829
}
830
- netdata_rwlock_unlock(&st->alerts.rwlock);
830
+ rw_spinlock_write_unlock(&st->alerts.spinlock);
831
}
832
833
void rrdcalc_delete_all(RRDHOST *host) {
database/rrdhost.c
-1
@@ -1260,7 +1260,6 @@ void rrdhost_free___while_having_rrd_wrlock(RRDHOST *host, bool force) {
1260
string_freez(host->health.health_default_recipient);
1261
string_freez(host->registry_hostname);
1262
simple_pattern_free(host->rrdpush_send_charts_matching);
1263
- netdata_rwlock_destroy(&host->health_log.alarm_log_rwlock);
1263
freez(host->node_id);
1264
1265
rrdfamily_index_destroy(host);
database/rrdset.c
+1
-3
@@ -143,7 +143,7 @@ static void rrdset_insert_callback(const DICTIONARY_ITEM *item __maybe_unused, v
143
| RRDSET_FLAG_SENDER_REPLICATION_FINISHED
144
;
145
146
- netdata_rwlock_init(&st->alerts.rwlock);
146
+ rw_spinlock_init(&st->alerts.spinlock);
147
148
if(st->rrd_memory_mode == RRD_MEMORY_MODE_SAVE || st->rrd_memory_mode == RRD_MEMORY_MODE_MAP) {
149
if(!rrdset_memory_load_or_create_map_save(st, st->rrd_memory_mode)) {
@@ -263,8 +263,6 @@ static void rrdset_delete_callback(const DICTIONARY_ITEM *item __maybe_unused, v
263
// ------------------------------------------------------------------------
264
// free it
265
266
- netdata_rwlock_destroy(&st->alerts.rwlock);
267
-
266
string_freez(st->id);
267
string_freez(st->name);
268
string_freez(st->parts.id);
database/sqlite/sqlite_aclk_alert.c
+7
-7
@@ -454,11 +454,11 @@ void sql_queue_existing_alerts_to_aclk(RRDHOST *host)
454
sqlite3_stmt *res = NULL;
455
int rc;
456
457
- netdata_rwlock_wrlock(&host->health_log.alarm_log_rwlock);
457
+ rw_spinlock_write_lock(&host->health_log.spinlock);
458
459
buffer_sprintf(sql, "delete from aclk_alert_%s; ", uuid_str);
460
if (unlikely(db_execute(db_meta, buffer_tostring(sql)))) {
461
- netdata_rwlock_unlock(&host->health_log.alarm_log_rwlock);
461
+ rw_spinlock_write_unlock(&host->health_log.spinlock);
462
buffer_free(sql);
463
return;
464
}
@@ -472,7 +472,7 @@ void sql_queue_existing_alerts_to_aclk(RRDHOST *host)
472
rc = sqlite3_prepare_v2(db_meta, buffer_tostring(sql), -1, &res, 0);
473
if (rc != SQLITE_OK) {
474
error_report("Failed to prepare statement when trying to queue existing alerts.");
475
- netdata_rwlock_unlock(&host->health_log.alarm_log_rwlock);
475
+ rw_spinlock_write_unlock(&host->health_log.spinlock);
476
buffer_free(sql);
477
return;
478
}
@@ -481,7 +481,7 @@ void sql_queue_existing_alerts_to_aclk(RRDHOST *host)
481
if (unlikely(rc != SQLITE_OK)) {
482
error_report("Failed to bind host_id for when trying to queue existing alerts.");
483
sqlite3_finalize(res);
484
- netdata_rwlock_unlock(&host->health_log.alarm_log_rwlock);
484
+ rw_spinlock_write_unlock(&host->health_log.spinlock);
485
buffer_free(sql);
486
return;
487
}
@@ -495,7 +495,7 @@ void sql_queue_existing_alerts_to_aclk(RRDHOST *host)
495
if (unlikely(rc != SQLITE_OK))
496
error_report("Failed to finalize statement to queue existing alerts, rc = %d", rc);
497
498
- netdata_rwlock_unlock(&host->health_log.alarm_log_rwlock);
498
+ rw_spinlock_write_unlock(&host->health_log.spinlock);
499
500
buffer_free(sql);
501
rrdhost_flag_set(host, RRDHOST_FLAG_ACLK_STREAM_ALERTS);
@@ -888,7 +888,7 @@ void aclk_push_alert_snapshot_event(char *node_id __maybe_unused)
888
char uuid_str[UUID_STR_LEN];
889
uuid_unparse_lower_fix(&host->host_uuid, uuid_str);
890
891
- netdata_rwlock_rdlock(&host->health_log.alarm_log_rwlock);
891
+ rw_spinlock_read_lock(&host->health_log.spinlock);
892
893
ALARM_ENTRY *ae = host->health_log.alarms;
894
@@ -973,7 +973,7 @@ void aclk_push_alert_snapshot_event(char *node_id __maybe_unused)
973
aclk_send_alarm_snapshot(snapshot_proto);
974
}
975
976
- netdata_rwlock_unlock(&host->health_log.alarm_log_rwlock);
976
+ rw_spinlock_read_unlock(&host->health_log.spinlock);
977
wc->alerts_snapshot_uuid = NULL;
978
979
freez(claim_id);
database/sqlite/sqlite_health.c
+2
-2
@@ -789,7 +789,7 @@ void sql_health_alarm_log_load(RRDHOST *host) {
789
}
790
foreach_rrdcalc_in_rrdhost_done(rc);
791
792
- netdata_rwlock_rdlock(&host->health_log.alarm_log_rwlock);
792
+ rw_spinlock_read_lock(&host->health_log.spinlock);
793
794
while (sqlite3_step_monitored(res) == SQLITE_ROW) {
795
ALARM_ENTRY *ae = NULL;
@@ -947,7 +947,7 @@ void sql_health_alarm_log_load(RRDHOST *host) {
947
loaded++;
948
}
949
950
- netdata_rwlock_unlock(&host->health_log.alarm_log_rwlock);
950
+ rw_spinlock_read_unlock(&host->health_log.spinlock);
951
952
dictionary_destroy(all_rrdcalcs);
953
all_rrdcalcs = NULL;
health/health.c
+7
-7
@@ -346,13 +346,13 @@ static void health_reload_host(RRDHOST *host) {
346
rrdcalctemplate_delete_all(host);
347
348
// invalidate all previous entries in the alarm log
349
- netdata_rwlock_rdlock(&host->health_log.alarm_log_rwlock);
349
+ rw_spinlock_read_lock(&host->health_log.spinlock);
350
ALARM_ENTRY *t;
351
for(t = host->health_log.alarms ; t ; t = t->next) {
352
if(t->new_status != RRDCALC_STATUS_REMOVED)
353
t->flags |= HEALTH_ENTRY_FLAG_UPDATED;
354
}
355
- netdata_rwlock_unlock(&host->health_log.alarm_log_rwlock);
355
+ rw_spinlock_read_unlock(&host->health_log.spinlock);
356
357
// reset all thresholds to all charts
358
RRDSET *st;
@@ -632,7 +632,7 @@ static inline void health_alarm_log_process(RRDHOST *host) {
632
uint32_t first_waiting = (host->health_log.alarms)?host->health_log.alarms->unique_id:0;
633
time_t now = now_realtime_sec();
634
635
- netdata_rwlock_rdlock(&host->health_log.alarm_log_rwlock);
635
+ rw_spinlock_read_lock(&host->health_log.spinlock);
636
637
ALARM_ENTRY *ae;
638
for(ae = host->health_log.alarms; ae && ae->unique_id >= host->health_last_processed_id; ae = ae->next) {
@@ -648,13 +648,13 @@ static inline void health_alarm_log_process(RRDHOST *host) {
648
}
649
}
650
651
- netdata_rwlock_unlock(&host->health_log.alarm_log_rwlock);
651
+ rw_spinlock_read_unlock(&host->health_log.spinlock);
652
653
// remember this for the next iteration
654
host->health_last_processed_id = first_waiting;
655
656
//delete those that are updated, no in progress execution, and is not repeating
657
- netdata_rwlock_wrlock(&host->health_log.alarm_log_rwlock);
657
+ rw_spinlock_write_lock(&host->health_log.spinlock);
658
659
ALARM_ENTRY *prev = NULL, *next = NULL;
660
for(ae = host->health_log.alarms; ae ; ae = next) {
@@ -686,7 +686,7 @@ static inline void health_alarm_log_process(RRDHOST *host) {
686
prev = ae;
687
}
688
689
- netdata_rwlock_unlock(&host->health_log.alarm_log_rwlock);
689
+ rw_spinlock_write_unlock(&host->health_log.spinlock);
690
}
691
692
static inline int rrdcalc_isrunnable(RRDCALC *rc, time_t now, time_t *next_run) {
@@ -815,7 +815,7 @@ static void initialize_health(RRDHOST *host)
815
conf_enabled_alarms = simple_pattern_create(config_get(CONFIG_SECTION_HEALTH, "enabled alarms", "*"), NULL,
816
SIMPLE_PATTERN_EXACT, true);
817
818
- netdata_rwlock_init(&host->health_log.alarm_log_rwlock);
818
+ rw_spinlock_init(&host->health_log.spinlock);
819
820
char filename[FILENAME_MAX + 1];
821
health/health_log.c
+6
-6
@@ -94,14 +94,14 @@ inline void health_alarm_log_add_entry(
94
__atomic_add_fetch(&host->health_transitions, 1, __ATOMIC_RELAXED);
95
96
// link it
97
- netdata_rwlock_wrlock(&host->health_log.alarm_log_rwlock);
97
+ rw_spinlock_write_lock(&host->health_log.spinlock);
98
ae->next = host->health_log.alarms;
99
host->health_log.alarms = ae;
100
host->health_log.count++;
101
- netdata_rwlock_unlock(&host->health_log.alarm_log_rwlock);
101
+ rw_spinlock_write_unlock(&host->health_log.spinlock);
102
103
// match previous alarms
104
- netdata_rwlock_rdlock(&host->health_log.alarm_log_rwlock);
104
+ rw_spinlock_read_lock(&host->health_log.spinlock);
105
ALARM_ENTRY *t;
106
for(t = host->health_log.alarms ; t ; t = t->next) {
107
if(t != ae && t->alarm_id == ae->alarm_id) {
@@ -121,7 +121,7 @@ inline void health_alarm_log_add_entry(
121
break;
122
}
123
}
124
- netdata_rwlock_unlock(&host->health_log.alarm_log_rwlock);
124
+ rw_spinlock_read_unlock(&host->health_log.spinlock);
125
126
health_alarm_log_save(host, ae);
127
}
@@ -145,7 +145,7 @@ inline void health_alarm_log_free_one_nochecks_nounlink(ALARM_ENTRY *ae) {
145
}
146
147
inline void health_alarm_log_free(RRDHOST *host) {
148
- netdata_rwlock_wrlock(&host->health_log.alarm_log_rwlock);
148
+ rw_spinlock_write_lock(&host->health_log.spinlock);
149
150
ALARM_ENTRY *ae;
151
while((ae = host->health_log.alarms)) {
@@ -153,5 +153,5 @@ inline void health_alarm_log_free(RRDHOST *host) {
153
health_alarm_log_free_one_nochecks_nounlink(ae);
154
}
155
156
- netdata_rwlock_unlock(&host->health_log.alarm_log_rwlock);
156
+ rw_spinlock_write_unlock(&host->health_log.spinlock);
157
}
web/api/formatters/json_wrapper.c
+4
-4
@@ -615,7 +615,7 @@ static void query_target_summary_alerts_v2(BUFFER *wb, QUERY_TARGET *qt, const c
615
QUERY_INSTANCE *qi = query_instance(qt, c);
616
RRDSET *st = rrdinstance_acquired_rrdset(qi->ria);
617
if (st) {
618
- netdata_rwlock_rdlock(&st->alerts.rwlock);
618
+ rw_spinlock_read_lock(&st->alerts.spinlock);
619
if (st->alerts.base) {
620
for (RRDCALC *rc = st->alerts.base; rc; rc = rc->next) {
621
z = dictionary_set(dict, string2str(rc->name), NULL, sizeof(*z));
@@ -642,7 +642,7 @@ static void query_target_summary_alerts_v2(BUFFER *wb, QUERY_TARGET *qt, const c
642
}
643
}
644
}
645
- netdata_rwlock_unlock(&st->alerts.rwlock);
645
+ rw_spinlock_read_unlock(&st->alerts.spinlock);
646
}
647
}
648
dfe_start_read(dict, z)
@@ -931,7 +931,7 @@ void rrdr_json_wrapper_begin(RRDR *r, BUFFER *wb) {
931
static void rrdset_rrdcalc_entries_v2(BUFFER *wb, RRDINSTANCE_ACQUIRED *ria) {
932
RRDSET *st = rrdinstance_acquired_rrdset(ria);
933
if(st) {
934
- netdata_rwlock_rdlock(&st->alerts.rwlock);
934
+ rw_spinlock_read_lock(&st->alerts.spinlock);
935
if(st->alerts.base) {
936
buffer_json_member_add_object(wb, "alerts");
937
for(RRDCALC *rc = st->alerts.base; rc ;rc = rc->next) {
@@ -946,7 +946,7 @@ static void rrdset_rrdcalc_entries_v2(BUFFER *wb, RRDINSTANCE_ACQUIRED *ria) {
946
}
947
buffer_json_object_close(wb);
948
}
949
- netdata_rwlock_unlock(&st->alerts.rwlock);
949
+ rw_spinlock_read_unlock(&st->alerts.spinlock);
950
}
951
}
952
web/api/formatters/rrdset2json.c
+2
-2
@@ -120,7 +120,7 @@ void rrdset2json(RRDSET *st, BUFFER *wb, size_t *dimensions_count, size_t *memor
120
buffer_strcat(wb, ",\n\t\t\t\"alarms\": {\n");
121
size_t alarms = 0;
122
RRDCALC *rc;
123
- netdata_rwlock_rdlock(&st->alerts.rwlock);
123
+ rw_spinlock_read_lock(&st->alerts.spinlock);
124
DOUBLE_LINKED_LIST_FOREACH_FORWARD(st->alerts.base, rc, prev, next) {
125
buffer_sprintf(
126
wb,
@@ -136,7 +136,7 @@ void rrdset2json(RRDSET *st, BUFFER *wb, size_t *dimensions_count, size_t *memor
136
137
alarms++;
138
}
139
- netdata_rwlock_unlock(&st->alerts.rwlock);
139
+ rw_spinlock_read_unlock(&st->alerts.spinlock);
140
buffer_sprintf(wb,
141
"\n\t\t\t}"
142
);