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:
Alexi Demers 2024-07-22 15:52:50 -04:00 committed by Anas Nashif
parent 32481b6418
commit bf41e53e00

View file

@ -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;
}