varnish-cache icon indicating copy to clipboard operation
varnish-cache copied to clipboard

vsc: Always perform volatile access to VSC values

Open dridi opened this issue 3 years ago • 4 comments

From @asadsa92's recent review of #3483:

Any side-effect to get rid off the volatile pointer?

There used to be two locations where pt->ptr was dereferenced as a volatile pointer and considering the effective volatility of VSCs we should probably generalize it in VSC_Value() where it was centralized.

dridi avatar Jan 05 '22 18:01 dridi

Can anyone help me understand the motivation? In my mind, the time scale of outdated values for non volatile access should be irrelevant to vsc clients.

nigoroll avatar Jan 07 '22 12:01 nigoroll

So, I only mentioned this as part of my review as I also wanted to understand whether the change was intended or simply a oversight.

Now looking:

  • The declaration is volatile: https://github.com/varnishcache/varnish-cache/blob/master/include/vapi/vsc.h#L52
  • The only place, which I could find, were it is updated: https://github.com/varnishcache/varnish-cache/blob/master/lib/libvarnishapi/vsc.c#L310 . This is updated through VSC_Iter -> vsc_add_seg -> vsc_fill_point

VSC_Iter is only called from VSC clients and the same goes for VSC_Value. So, I think @nigoroll might be correct that this is not needed. The compiler "sees" all modifications of pt->ptr and therefore should be free to optimize the access. Unless, we expect the libvarnishapi to change separately from the VSC clients in the installation. The point is that we have no external access to pt->ptr so volatile should no be needed.

EDIT: I was able to find the origin of the volatile member: https://github.com/varnishcache/varnish-cache/commit/f25134aa6eff8ea23a6c64cb2c0123b7ae853589 (11 years ago, AFAICT it has always been volatile) @bsdphk, maybe you got some input here that I might have overseen.

asadsa92 avatar Jan 07 '22 12:01 asadsa92

@asadsa92 thank you for the clarification and research.

Within varnishd (at the write end for statistics), volatile kind-of makes sense: Because we update values (e.g. increase/decrese), outdated values cause inaccurate statistics.

But volatile is not the solution, concurrent access can still happen and will cause wrong values. Thus, we already serialize access to the most important statistics, and for this case volatile is useless and wasteful.

So I think a proper solution would be to have stats with

  • either a non-volatile declaration and locking or
  • an atomic declaration.

nigoroll avatar Jan 07 '22 13:01 nigoroll

"Within varnishd (at the write end for statistics), volatile kind-of makes sense: Because we update values (e.g. increase/decrese), outdated values cause inaccurate statistics."

That volatile in varnishd is to make sure the VSM is updated in at timely matter, as @nigoroll mentions, it is not enough to protect the read-modify-write operation itself, we use locks for that.

Similarly on the client side, we need volatile to explain to the compiler that the contents of the VSM changes under us.

To what extent they actually make any difference in the real world is a damn good question, which is impossible to find the answer to, except by disassembly of suspected code.

bsdphk avatar Jan 10 '22 12:01 bsdphk

Does this PR still serve a purpose?

nigoroll avatar Nov 08 '22 14:11 nigoroll

As far as I can tell, the proposed volatile makes no difference, so timing out this ticket.

bsdphk avatar Jan 23 '23 14:01 bsdphk