[Spice-devel] [server PATCH 4/4] stat_file_add_node: add "locked" comment
Frediano Ziglio
fziglio at redhat.com
Mon Dec 11 09:19:49 UTC 2017
>
> On 12/10/2017 04:35 PM, Frediano Ziglio wrote:
> >>>
> >>> Coverity complains node->flags is accessed without locking
> >>> stat_file->lock.
> >>> However the function stat_file_add_node is only called (from
> >>> stat_file_add_counter) when the lock is taken.
> >>>
> >>
> >> No, this is false. The function handle the lock.
>
> You are right. I made a mistake.
> The problem reported is in stat_file_add_counter()
>
>
> We can fix it by locking/unlocking there:
> diff --git a/server/stat-file.c b/server/stat-file.c
> index 2797fd739..84f409a46 100644
> --- a/server/stat-file.c
> +++ b/server/stat-file.c
> @@ -189,8 +189,10 @@ stat_file_add_counter(RedStatFile *stat_file,
> StatNodeRef parent, const char *na
> if (ref == INVALID_STAT_REF) {
> return NULL;
> }
> + pthread_mutex_lock(&stat_file->lock);
> node = &stat_file->stat->nodes[ref];
> node->flags |= SPICE_STAT_NODE_FLAG_VALUE;
> + pthread_mutex_unlock(&stat_file->lock);
> return &node->value;
> }
>
Why not
return NULL;
}
node = &stat_file->stat->nodes[ref];
- node->flags |= SPICE_STAT_NODE_FLAG_VALUE;
+ __sync_or_and_fetch(&node->flags, SPICE_STAT_NODE_FLAG_VALUE);
return &node->value;
}
static void stat_file_remove(RedStatFile *stat_file, SpiceStatNode *node)
we already use __sync builtins in utils.h.
>
> Your solution below also looks good to me
> and does not add another lock, but probably
> better to pass "additional_flags" (or "extra_flags")
> instead of "flags" such that visible ? ... would appear
> once as it is currently in the code.
>
> Thanks,
> Uri.
>
> >> The problem happens because stat_file_add_counter add a flag without
> >> locking.
> >> However in this case this is not much of a problem as the this is the last
> >> change of
> >> the flag and maximum cause a temporary view of the node as not counter.
> >>
> >>> Add comment so it's clear.
> >>>
> >>> Signed-off-by: Uri Lublin <uril at redhat.com>
> >>> ---
> >>> server/stat-file.c | 1 +
> >>> 1 file changed, 1 insertion(+)
> >>>
> >>> diff --git a/server/stat-file.c b/server/stat-file.c
> >>> index 2797fd739..9aff8cd72 100644
> >>> --- a/server/stat-file.c
> >>> +++ b/server/stat-file.c
> >>> @@ -139,6 +139,7 @@ static void reds_insert_stat_node(RedStatFile
> >>> *stat_file,
> >>> StatNodeRef parent, St
> >>> }
> >>> }
> >>>
> >>> +/* Called with stat_file->lock locked */
> >>> StatNodeRef
> >>> stat_file_add_node(RedStatFile *stat_file, StatNodeRef parent, const
> >>> char
> >>> *name, int visible)
> >>> {
> >>
> >
> > This should work
> >
> >
> > diff --git a/server/stat-file.c b/server/stat-file.c
> > index 2797fd73..c52c266c 100644
> > --- a/server/stat-file.c
> > +++ b/server/stat-file.c
> > @@ -139,8 +139,9 @@ static void reds_insert_stat_node(RedStatFile
> > *stat_file, StatNodeRef parent, St
> > }
> > }
> >
> > -StatNodeRef
> > -stat_file_add_node(RedStatFile *stat_file, StatNodeRef parent, const char
> > *name, int visible)
> > +static StatNodeRef
> > +stat_file_add_node_flags(RedStatFile *stat_file, StatNodeRef parent, const
> > char *name,
> > + uint32_t flags)
> > {
> > StatNodeRef ref;
> > SpiceStatNode *node;
> > @@ -169,8 +170,7 @@ stat_file_add_node(RedStatFile *stat_file, StatNodeRef
> > parent, const char *name,
> > stat_file->stat->generation++;
> > stat_file->stat->num_of_nodes++;
> > node->value = 0;
> > - node->flags = SPICE_STAT_NODE_FLAG_ENABLED |
> > - (visible ? SPICE_STAT_NODE_FLAG_VISIBLE : 0);
> > + node->flags = SPICE_STAT_NODE_FLAG_ENABLED | flags;
> > g_strlcpy(node->name, name, sizeof(node->name));
> > reds_insert_stat_node(stat_file, parent, ref);
> > pthread_mutex_unlock(&stat_file->lock);
> > @@ -180,17 +180,25 @@ stat_file_add_node(RedStatFile *stat_file,
> > StatNodeRef parent, const char *name,
> > return INVALID_STAT_REF;
> > }
> >
> > +StatNodeRef
> > +stat_file_add_node(RedStatFile *stat_file, StatNodeRef parent, const char
> > *name, int visible)
> > +{
> > + uint32_t flags = visible ? SPICE_STAT_NODE_FLAG_VISIBLE : 0;
> > + return stat_file_add_node_flags(stat_file, parent, name, flags);
> > +}
> > +
> > uint64_t *
> > stat_file_add_counter(RedStatFile *stat_file, StatNodeRef parent, const
> > char *name, int visible)
> > {
> > - StatNodeRef ref = stat_file_add_node(stat_file, parent, name,
> > visible);
> > + uint32_t flags = visible ? SPICE_STAT_NODE_FLAG_VISIBLE : 0;
> > + flags |= SPICE_STAT_NODE_FLAG_VALUE;
> > + StatNodeRef ref = stat_file_add_node_flags(stat_file, parent, name,
> > flags);
> > SpiceStatNode *node;
> >
> > if (ref == INVALID_STAT_REF) {
> > return NULL;
> > }
> > node = &stat_file->stat->nodes[ref];
> > - node->flags |= SPICE_STAT_NODE_FLAG_VALUE;
> > return &node->value;
> > }
> >
> >
> >
> > Frediano
> >
>
>
More information about the Spice-devel
mailing list