[master] 69dfe4980 vsc: New VSC_Value() function to clamp gauges
Dridi Boukelmoune
dridi.boukelmoune at gmail.com
Mon Jan 11 17:06:07 UTC 2021
commit 69dfe49809322242037dea26e883ed7d5a5d21a6
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date: Tue Oct 20 16:13:58 2020 +0200
vsc: New VSC_Value() function to clamp gauges
When gauges are incremented and decremented by different threads, there
is a chance that decrements are published first, provoking an underflow
of the VSC. Values with the MSB set are considered underflowed, adjusted
to zero instead.
diff --git a/bin/varnishstat/varnishstat.c b/bin/varnishstat/varnishstat.c
index 75c88311f..695ca092c 100644
--- a/bin/varnishstat/varnishstat.c
+++ b/bin/varnishstat/varnishstat.c
@@ -67,7 +67,7 @@ do_xml_cb(void *priv, const struct VSC_point * const pt)
if (pt == NULL)
return (0);
AZ(strcmp(pt->ctype, "uint64_t"));
- val = *(const volatile uint64_t*)pt->ptr;
+ val = VSC_Value(pt);
printf("\t<stat>\n");
printf("\t\t<name>%s</name>\n", pt->name);
@@ -106,7 +106,7 @@ do_json_cb(void *priv, const struct VSC_point * const pt)
return (0);
AZ(strcmp(pt->ctype, "uint64_t"));
- val = (uintmax_t)*(const volatile uint64_t*)pt->ptr;
+ val = (uintmax_t)VSC_Value(pt);
sep = priv;
@@ -167,7 +167,7 @@ do_once_cb_first(void *priv, const struct VSC_point * const pt)
AZ(strcmp(pt->ctype, "uint64_t"));
if (strcmp(pt->name, "MAIN.uptime"))
return (0);
- val = *(const volatile uint64_t*)pt->ptr;
+ val = VSC_Value(pt);
op->up = (double)val;
return (1);
}
@@ -183,7 +183,7 @@ do_once_cb(void *priv, const struct VSC_point * const pt)
return (0);
op = priv;
AZ(strcmp(pt->ctype, "uint64_t"));
- val = *(const volatile uint64_t*)pt->ptr;
+ val = VSC_Value(pt);
i = 0;
i += printf("%s", pt->name);
if (i >= op->pad)
diff --git a/bin/varnishstat/varnishstat_curses.c b/bin/varnishstat/varnishstat_curses.c
index f7c486db1..4c3ff9127 100644
--- a/bin/varnishstat/varnishstat_curses.c
+++ b/bin/varnishstat/varnishstat_curses.c
@@ -256,7 +256,7 @@ sample_points(void)
VTAILQ_FOREACH(pt, &ptlist, list) {
AN(pt->vpt);
AN(pt->vpt->ptr);
- v = *pt->vpt->ptr;
+ v = VSC_Value(pt->vpt);
if (v == 0 && !pt->seen)
continue;
if (!pt->seen) {
@@ -1104,7 +1104,7 @@ newpt(void *priv, const struct VSC_point *const vpt)
rebuild |= REBUILD_NEXT;
AN(pt);
pt->vpt = vpt;
- pt->last = *pt->vpt->ptr;
+ pt->last = VSC_Value(vpt);
pt->ma_10.nmax = 10;
pt->ma_100.nmax = 100;
pt->ma_1000.nmax = 1000;
diff --git a/bin/varnishtest/vtc_varnish.c b/bin/varnishtest/vtc_varnish.c
index 4698aa4e9..b051b8e08 100644
--- a/bin/varnishtest/vtc_varnish.c
+++ b/bin/varnishtest/vtc_varnish.c
@@ -864,7 +864,7 @@ do_stat_dump_cb(void *priv, const struct VSC_point * const pt)
if (strcmp(pt->ctype, "uint64_t"))
return (0);
- u = *pt->ptr;
+ u = VSC_Value(pt);
if (strcmp(dp->arg, "*")) {
if (fnmatch(dp->arg, pt->name, 0))
@@ -926,7 +926,7 @@ do_expect_cb(void *priv, const struct VSC_point * const pt)
if (!sp->lhs.good && stat_match(sp->lhs.pattern, pt->name) == 0) {
AZ(strcmp(pt->ctype, "uint64_t"));
AN(pt->ptr);
- sp->lhs.val = *pt->ptr;
+ sp->lhs.val = VSC_Value(pt);
sp->lhs.good = 1;
}
@@ -936,7 +936,7 @@ do_expect_cb(void *priv, const struct VSC_point * const pt)
stat_match(sp->rhs.pattern, pt->name) == 0) {
AZ(strcmp(pt->ctype, "uint64_t"));
AN(pt->ptr);
- sp->rhs.val = *pt->ptr;
+ sp->rhs.val = VSC_Value(pt);
sp->rhs.good = 1;
}
diff --git a/include/vapi/vsc.h b/include/vapi/vsc.h
index c09d6b150..5eaa85c41 100644
--- a/include/vapi/vsc.h
+++ b/include/vapi/vsc.h
@@ -159,4 +159,15 @@ const struct VSC_level_desc *VSC_ChangeLevel(const struct VSC_level_desc*, int);
* Change a level up or down.
*/
+static inline uint64_t
+VSC_Value(const struct VSC_point * const pt)
+{
+ uint64_t val;
+
+ val = *pt->ptr;
+ if (pt->semantics == 'g' && val > INT64_MAX)
+ val = 0;
+ return (val);
+}
+
#endif /* VAPI_VSC_H_INCLUDED */
More information about the varnish-commit
mailing list