Commit c59428b1 authored by davidcunado-arm's avatar davidcunado-arm Committed by GitHub
Browse files

Merge pull request #761 from soby-mathew/sm/bakery_lock_fixes

Fix normal memory bakery lock implementation
parents 805972fe 95c12559
/* /*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -90,6 +90,22 @@ extern void *__PERCPU_BAKERY_LOCK_SIZE__; ...@@ -90,6 +90,22 @@ extern void *__PERCPU_BAKERY_LOCK_SIZE__;
#define read_cache_op(addr, cached) if (cached) \ #define read_cache_op(addr, cached) if (cached) \
dccivac((uintptr_t)addr) dccivac((uintptr_t)addr)
/* Helper function to check if the lock is acquired */
static inline int is_lock_acquired(const bakery_info_t *my_bakery_info,
int is_cached)
{
/*
* Even though lock data is updated only by the owning cpu and
* appropriate cache maintenance operations are performed,
* if the previous update was done when the cpu was not participating
* in coherency, then there is a chance that cache maintenance
* operations were not propagated to all the caches in the system.
* Hence do a `read_cache_op()` prior to read.
*/
read_cache_op(my_bakery_info, is_cached);
return !!(bakery_ticket_number(my_bakery_info->lock_data));
}
static unsigned int bakery_get_ticket(bakery_lock_t *lock, static unsigned int bakery_get_ticket(bakery_lock_t *lock,
unsigned int me, int is_cached) unsigned int me, int is_cached)
{ {
...@@ -104,12 +120,8 @@ static unsigned int bakery_get_ticket(bakery_lock_t *lock, ...@@ -104,12 +120,8 @@ static unsigned int bakery_get_ticket(bakery_lock_t *lock,
my_bakery_info = get_bakery_info(me, lock); my_bakery_info = get_bakery_info(me, lock);
assert(my_bakery_info); assert(my_bakery_info);
/* /* Prevent recursive acquisition.*/
* Prevent recursive acquisition. assert(!is_lock_acquired(my_bakery_info, is_cached));
* Since lock data is written to and cleaned by the owning cpu, it
* doesn't require any cache operations prior to reading the lock data.
*/
assert(!bakery_ticket_number(my_bakery_info->lock_data));
/* /*
* Tell other contenders that we are through the bakery doorway i.e. * Tell other contenders that we are through the bakery doorway i.e.
...@@ -222,7 +234,8 @@ void bakery_lock_release(bakery_lock_t *lock) ...@@ -222,7 +234,8 @@ void bakery_lock_release(bakery_lock_t *lock)
unsigned int is_cached = read_sctlr_el3() & SCTLR_C_BIT; unsigned int is_cached = read_sctlr_el3() & SCTLR_C_BIT;
my_bakery_info = get_bakery_info(plat_my_core_pos(), lock); my_bakery_info = get_bakery_info(plat_my_core_pos(), lock);
assert(bakery_ticket_number(my_bakery_info->lock_data));
assert(is_lock_acquired(my_bakery_info, is_cached));
my_bakery_info->lock_data = 0; my_bakery_info->lock_data = 0;
write_cache_op(my_bakery_info, is_cached); write_cache_op(my_bakery_info, is_cached);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment