@cryptotaxi247 / netdata-1 / commits / b12edb120

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 );