From eb5a78719a237f540360a4ea4b2fe860cb3c5051 Mon Sep 17 00:00:00 2001 From: Raghavendra Rao Ananta Date: Wed, 5 Feb 2020 11:07:04 -0800 Subject: [PATCH] haven: Convert the cap entry locks to spinlocks There's a potential chance that the clients can request to send or receive the data from an interrupt context. Hence, convert the cap_entry_lock from mutex to a spinlock. Change-Id: Ic314a32f7a8007308c0a397e0cc44f16441c58d4 Signed-off-by: Raghavendra Rao Ananta Signed-off-by: Murali Nalajala --- drivers/virt/haven/hh_msgq.c | 64 ++++++++++++++---------------------- 1 file changed, 25 insertions(+), 39 deletions(-) diff --git a/drivers/virt/haven/hh_msgq.c b/drivers/virt/haven/hh_msgq.c index 331602efd533..0dd22d7c0b0f 100644 --- a/drivers/virt/haven/hh_msgq.c +++ b/drivers/virt/haven/hh_msgq.c @@ -6,7 +6,6 @@ #include #include -#include #include #include #include @@ -24,7 +23,7 @@ struct hh_msgq_desc { struct hh_msgq_cap_table { struct hh_msgq_desc *client_desc; - struct mutex cap_entry_lock; + spinlock_t cap_entry_lock; hh_capid_t tx_cap_id; hh_capid_t rx_cap_id; @@ -132,8 +131,7 @@ int hh_msgq_recv(void *msgq_client_desc, cap_table_entry = &hh_msgq_cap_table[client_desc->label]; - if (mutex_lock_interruptible(&cap_table_entry->cap_entry_lock)) - return -ERESTARTSYS; + spin_lock(&cap_table_entry->cap_entry_lock); if (cap_table_entry->client_desc != client_desc) { pr_err("%s: Invalid client descriptor\n", __func__); @@ -155,7 +153,7 @@ int hh_msgq_recv(void *msgq_client_desc, goto err; } - mutex_unlock(&cap_table_entry->cap_entry_lock); + spin_unlock(&cap_table_entry->cap_entry_lock); *buff = kzalloc(HH_MSGQ_MAX_MSG_SIZE_BYTES, GFP_KERNEL); if (!(*buff)) @@ -185,7 +183,7 @@ buff_free: return ret; err: - mutex_unlock(&cap_table_entry->cap_entry_lock); + spin_unlock(&cap_table_entry->cap_entry_lock); return ret; } EXPORT_SYMBOL(hh_msgq_recv); @@ -254,8 +252,7 @@ int hh_msgq_send(void *msgq_client_desc, cap_table_entry = &hh_msgq_cap_table[client_desc->label]; - if (mutex_lock_interruptible(&cap_table_entry->cap_entry_lock)) - return -ERESTARTSYS; + spin_lock(&cap_table_entry->cap_entry_lock); if (cap_table_entry->client_desc != client_desc) { pr_err("%s: Invalid client descriptor\n", __func__); @@ -277,13 +274,11 @@ int hh_msgq_send(void *msgq_client_desc, goto err; } - mutex_unlock(&cap_table_entry->cap_entry_lock); + spin_unlock(&cap_table_entry->cap_entry_lock); do { - if (cap_table_entry->tx_full && (flags & HH_MSGQ_NONBLOCK)) { - ret = -EAGAIN; - goto err; - } + if (cap_table_entry->tx_full && (flags & HH_MSGQ_NONBLOCK)) + return -EAGAIN; if (wait_event_interruptible(cap_table_entry->tx_wq, !cap_table_entry->tx_full)) @@ -300,7 +295,7 @@ int hh_msgq_send(void *msgq_client_desc, return ret; err: - mutex_unlock(&cap_table_entry->cap_entry_lock); + spin_unlock(&cap_table_entry->cap_entry_lock); return ret; } EXPORT_SYMBOL(hh_msgq_send); @@ -320,40 +315,35 @@ void *hh_msgq_register(enum hh_msgq_label label) { struct hh_msgq_cap_table *cap_table_entry; struct hh_msgq_desc *client_desc; - int ret; if (label < 0 || label >= HH_MSGQ_LABEL_MAX) return ERR_PTR(-EINVAL); cap_table_entry = &hh_msgq_cap_table[label]; - if (mutex_lock_interruptible(&cap_table_entry->cap_entry_lock)) - return ERR_PTR(-ERESTARTSYS); + spin_lock(&cap_table_entry->cap_entry_lock); /* Multiple clients cannot register to the same label (msgq) */ if (cap_table_entry->client_desc) { - ret = -EBUSY; - goto err; + spin_unlock(&cap_table_entry->cap_entry_lock); + return ERR_PTR(-EBUSY); } + spin_unlock(&cap_table_entry->cap_entry_lock); + client_desc = kzalloc(sizeof(*client_desc), GFP_KERNEL); - if (!client_desc) { - ret = ENOMEM; - goto err; - } + if (!client_desc) + return ERR_PTR(ENOMEM); client_desc->label = label; + spin_lock(&cap_table_entry->cap_entry_lock); cap_table_entry->client_desc = client_desc; + spin_unlock(&cap_table_entry->cap_entry_lock); pr_info("hh_msgq: Registered client for label: %d\n", label); - mutex_unlock(&cap_table_entry->cap_entry_lock); return client_desc; - -err: - mutex_unlock(&cap_table_entry->cap_entry_lock); - return ERR_PTR(ret); } EXPORT_SYMBOL(hh_msgq_register); @@ -374,20 +364,19 @@ int hh_msgq_unregister(void *msgq_client_desc) cap_table_entry = &hh_msgq_cap_table[client_desc->label]; - if (mutex_lock_interruptible(&cap_table_entry->cap_entry_lock)) - return -ERESTARTSYS; + spin_lock(&cap_table_entry->cap_entry_lock); /* Is the client trying to free someone else's msgq? */ if (cap_table_entry->client_desc != client_desc) { pr_err("%s: Trying to free invalid client descriptor!\n", __func__); - mutex_unlock(&cap_table_entry->cap_entry_lock); + spin_unlock(&cap_table_entry->cap_entry_lock); return -EINVAL; } cap_table_entry->client_desc = NULL; - mutex_unlock(&cap_table_entry->cap_entry_lock); + spin_unlock(&cap_table_entry->cap_entry_lock); pr_info("%s: Unregistered client for label: %d\n", __func__, client_desc->label); @@ -416,8 +405,7 @@ int hh_msgq_populate_cap_info(enum hh_msgq_label label, u64 cap_id, cap_table_entry = &hh_msgq_cap_table[label]; - if (mutex_lock_interruptible(&cap_table_entry->cap_entry_lock)) - return -ERESTARTSYS; + spin_lock(&cap_table_entry->cap_entry_lock); if (direction == HH_MSGQ_DIRECTION_TX) { ret = request_irq(irq, hh_msgq_tx_isr, 0, @@ -441,7 +429,7 @@ int hh_msgq_populate_cap_info(enum hh_msgq_label label, u64 cap_id, goto err; } - mutex_unlock(&cap_table_entry->cap_entry_lock); + spin_unlock(&cap_table_entry->cap_entry_lock); pr_debug( "%s: label: %d; cap_id: %llu; dir: %d; irq: %d\n", @@ -450,7 +438,7 @@ int hh_msgq_populate_cap_info(enum hh_msgq_label label, u64 cap_id, return 0; err: - mutex_unlock(&cap_table_entry->cap_entry_lock); + spin_unlock(&cap_table_entry->cap_entry_lock); return ret; } EXPORT_SYMBOL(hh_msgq_populate_cap_info); @@ -468,8 +456,6 @@ static void hh_msgq_cleanup(int begin_idx) kfree(cap_table_entry->tx_irq_name); kfree(cap_table_entry->rx_irq_name); - - mutex_destroy(&cap_table_entry->cap_entry_lock); } } @@ -490,7 +476,7 @@ static int __init hh_msgq_init(void) init_waitqueue_head(&cap_table_entry->rx_wq); spin_lock_init(&cap_table_entry->tx_lock); spin_lock_init(&cap_table_entry->rx_lock); - mutex_init(&cap_table_entry->cap_entry_lock); + spin_lock_init(&cap_table_entry->cap_entry_lock); cap_table_entry->tx_irq_name = kasprintf(GFP_KERNEL, "hh_msgq_tx_%d", i);