disk: disk_access: changed mutex for a spinlock
disk_access functions were called from an interupt context, thus crashing on mutexes (no sleep is allowed in interrupt context). The usage of a spinlock is permitted. The functions guarded by the spinlock are executed very quickly anyway, so the spinlock is applicable. Signed-off-by: Alexi Demers <alexi.demers@axceta.com>
This commit is contained in:
parent
32481b6418
commit
bf41e53e00
1 changed files with 16 additions and 21 deletions
|
|
@ -22,15 +22,15 @@ LOG_MODULE_REGISTER(disk);
|
|||
static sys_dlist_t disk_access_list = SYS_DLIST_STATIC_INIT(&disk_access_list);
|
||||
|
||||
/* lock to protect storage layer registration */
|
||||
static K_MUTEX_DEFINE(mutex);
|
||||
static struct k_spinlock lock;
|
||||
|
||||
struct disk_info *disk_access_get_di(const char *name)
|
||||
{
|
||||
struct disk_info *disk = NULL, *itr;
|
||||
size_t name_len = strlen(name);
|
||||
sys_dnode_t *node;
|
||||
k_spinlock_key_t spinlock_key = k_spin_lock(&lock);
|
||||
|
||||
k_mutex_lock(&mutex, K_FOREVER);
|
||||
SYS_DLIST_FOR_EACH_NODE(&disk_access_list, node) {
|
||||
itr = CONTAINER_OF(node, struct disk_info, node);
|
||||
|
||||
|
|
@ -49,7 +49,7 @@ struct disk_info *disk_access_get_di(const char *name)
|
|||
break;
|
||||
}
|
||||
}
|
||||
k_mutex_unlock(&mutex);
|
||||
k_spin_unlock(&lock, spinlock_key);
|
||||
|
||||
return disk;
|
||||
}
|
||||
|
|
@ -167,52 +167,47 @@ int disk_access_ioctl(const char *pdrv, uint8_t cmd, void *buf)
|
|||
|
||||
int disk_access_register(struct disk_info *disk)
|
||||
{
|
||||
int rc = 0;
|
||||
k_spinlock_key_t spinlock_key;
|
||||
|
||||
k_mutex_lock(&mutex, K_FOREVER);
|
||||
if ((disk == NULL) || (disk->name == NULL)) {
|
||||
LOG_ERR("invalid disk interface!!");
|
||||
rc = -EINVAL;
|
||||
goto reg_err;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (disk_access_get_di(disk->name) != NULL) {
|
||||
LOG_ERR("disk interface already registered!!");
|
||||
rc = -EINVAL;
|
||||
goto reg_err;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Initialize reference count to zero */
|
||||
disk->refcnt = 0U;
|
||||
|
||||
spinlock_key = k_spin_lock(&lock);
|
||||
/* append to the disk list */
|
||||
sys_dlist_append(&disk_access_list, &disk->node);
|
||||
LOG_DBG("disk interface(%s) registered", disk->name);
|
||||
reg_err:
|
||||
k_mutex_unlock(&mutex);
|
||||
return rc;
|
||||
k_spin_unlock(&lock, spinlock_key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int disk_access_unregister(struct disk_info *disk)
|
||||
{
|
||||
int rc = 0;
|
||||
k_spinlock_key_t spinlock_key;
|
||||
|
||||
k_mutex_lock(&mutex, K_FOREVER);
|
||||
if ((disk == NULL) || (disk->name == NULL)) {
|
||||
LOG_ERR("invalid disk interface!!");
|
||||
rc = -EINVAL;
|
||||
goto unreg_err;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (disk_access_get_di(disk->name) == NULL) {
|
||||
LOG_ERR("disk interface not registered!!");
|
||||
rc = -EINVAL;
|
||||
goto unreg_err;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
spinlock_key = k_spin_lock(&lock);
|
||||
/* remove disk node from the list */
|
||||
sys_dlist_remove(&disk->node);
|
||||
k_spin_unlock(&lock, spinlock_key);
|
||||
LOG_DBG("disk interface(%s) unregistered", disk->name);
|
||||
unreg_err:
|
||||
k_mutex_unlock(&mutex);
|
||||
return rc;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue