Skip to content

Commit 580579a

Browse files
Tomas Winklerlijinxia
authored andcommitted
dm: mei: Use compare and swap primitive for refcnt.
Simple atomic add/dec do no guarantee reference count full synchronization without a lock. Compare and swap operations are required for correct implementation. Tracked-On: #1875 Signed-off-by: Shuo A Liu <shuo.a.liu@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Acked-by: Yin Fengwei <fengwei.yin@intel.com>
1 parent b104722 commit 580579a

File tree

1 file changed

+30
-4
lines changed

1 file changed

+30
-4
lines changed

devicemodel/hw/pci/virtio/virtio_mei.c

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,16 +140,43 @@ struct refcnt {
140140
int count;
141141
};
142142

143-
static inline void
143+
static inline int atomic_read(const struct refcnt *ref)
144+
{
145+
return *(volatile int *)&ref->count;
146+
}
147+
148+
static inline int
144149
refcnt_get(const struct refcnt *ref)
145150
{
146-
__sync_add_and_fetch((int *)&ref->count, 1);
151+
int new, val;
152+
153+
do {
154+
val = atomic_read(ref);
155+
if (val == 0)
156+
return 0;
157+
158+
new = val + 1;
159+
/* check for overflow */
160+
assert(new > 0);
161+
162+
} while (!__sync_bool_compare_and_swap((int *)&ref->count, val, new));
163+
164+
return new;
147165
}
148166

149167
static inline void
150168
refcnt_put(const struct refcnt *ref)
151169
{
152-
if (__sync_sub_and_fetch((int *)&ref->count, 1) == 0)
170+
int new, val;
171+
172+
do {
173+
val = atomic_read(ref);
174+
if (val == 0)
175+
return;
176+
new = val - 1;
177+
} while (!__sync_bool_compare_and_swap((int *)&ref->count, val, new));
178+
179+
if (new == 0)
153180
ref->destroy(ref);
154181
}
155182

@@ -803,7 +830,6 @@ static int vmei_me_client_scan_list(struct virtio_mei *vmei)
803830

804831
if (ent->d_type == DT_DIR &&
805832
is_prefix("mei::", ent->d_name, DEV_NAME_SIZE)) {
806-
807833
struct mei_client_properties props;
808834

809835
memset(&props, 0, sizeof(props));

0 commit comments

Comments
 (0)