Loading drivers/soc/qcom/hab/ghs_comm.c +9 −7 Original line number Diff line number Diff line /* Copyright (c) 2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -43,19 +43,20 @@ int physical_channel_send(struct physical_channel *pchan, struct ghs_vdev *dev = (struct ghs_vdev *)pchan->hyp_data; GIPC_Result result; uint8_t *msg; int irqs_disabled = irqs_disabled(); spin_lock_bh(&dev->io_lock); hab_spin_lock(&dev->io_lock, irqs_disabled); result = GIPC_PrepareMessage(dev->endpoint, sizebytes+sizeof(*header), (void **)&msg); if (result == GIPC_Full) { spin_unlock_bh(&dev->io_lock); hab_spin_unlock(&dev->io_lock, irqs_disabled); /* need to wait for space! */ pr_err("failed to reserve send msg for %zd bytes\n", sizebytes+sizeof(*header)); return -EBUSY; } else if (result != GIPC_Success) { spin_unlock_bh(&dev->io_lock); hab_spin_unlock(&dev->io_lock, irqs_disabled); pr_err("failed to send due to error %d\n", result); return -ENOMEM; } Loading @@ -77,7 +78,7 @@ int physical_channel_send(struct physical_channel *pchan, result = GIPC_IssueMessage(dev->endpoint, sizebytes+sizeof(*header), header->id_type_size); spin_unlock_bh(&dev->io_lock); hab_spin_unlock(&dev->io_lock, irqs_disabled); if (result != GIPC_Success) { pr_err("send error %d, sz %zd, prot %x\n", result, sizebytes+sizeof(*header), Loading @@ -98,6 +99,7 @@ void physical_channel_rx_dispatch(unsigned long physical_channel) uint32_t events; unsigned long flags; int irqs_disabled = irqs_disabled(); spin_lock_irqsave(&pchan->rxbuf_lock, flags); events = kgipc_dequeue_events(dev->endpoint); Loading @@ -111,7 +113,7 @@ void physical_channel_rx_dispatch(unsigned long physical_channel) dev->name, pchan->vmid_remote); if (events & (GIPC_EVENT_RECEIVEREADY)) { spin_lock_bh(&pchan->rxbuf_lock); hab_spin_lock(&pchan->rxbuf_lock, irqs_disabled); while (1) { dev->read_size = 0; dev->read_offset = 0; Loading @@ -133,7 +135,7 @@ void physical_channel_rx_dispatch(unsigned long physical_channel) result, dev->read_size); break; } spin_unlock_bh(&pchan->rxbuf_lock); hab_spin_unlock(&pchan->rxbuf_lock, irqs_disabled); } if (events & (GIPC_EVENT_SENDREADY)) Loading drivers/soc/qcom/hab/hab.h +33 −1 Original line number Diff line number Diff line /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -577,6 +577,38 @@ int hab_stat_show_expimp(struct hab_driver *drv, int pid, char *buf, int sz); int hab_stat_init_sub(struct hab_driver *drv); int hab_stat_deinit_sub(struct hab_driver *drv); static inline void hab_spin_lock(spinlock_t *lock, int irqs_disabled) { if (irqs_disabled) spin_lock(lock); else spin_lock_bh(lock); } static inline void hab_spin_unlock(spinlock_t *lock, int irqs_disabled) { if (irqs_disabled) spin_unlock(lock); else spin_unlock_bh(lock); } static inline void hab_write_lock(rwlock_t *lock, int irqs_disabled) { if (irqs_disabled) write_lock(lock); else write_lock_bh(lock); } static inline void hab_write_unlock(rwlock_t *lock, int irqs_disabled) { if (irqs_disabled) write_unlock(lock); else write_unlock_bh(lock); } /* Global singleton HAB instance */ extern struct hab_driver hab_driver; Loading drivers/soc/qcom/hab/hab_msg.c +18 −11 Original line number Diff line number Diff line /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading @@ -15,10 +15,12 @@ static int hab_rx_queue_empty(struct virtual_channel *vchan) { int ret; int irqs_disabled = irqs_disabled(); spin_lock_bh(&vchan->rx_lock); hab_spin_lock(&vchan->rx_lock, irqs_disabled); ret = list_empty(&vchan->rx_list); spin_unlock_bh(&vchan->rx_lock); hab_spin_unlock(&vchan->rx_lock, irqs_disabled); return ret; } Loading Loading @@ -56,6 +58,7 @@ hab_msg_dequeue(struct virtual_channel *vchan, struct hab_message **msg, int ret = 0; int wait = !(flags & HABMM_SOCKET_RECV_FLAGS_NON_BLOCKING); int interruptible = !(flags & HABMM_SOCKET_RECV_FLAGS_UNINTERRUPTIBLE); int irqs_disabled = irqs_disabled(); if (wait) { if (hab_rx_queue_empty(vchan)) { Loading @@ -75,7 +78,7 @@ hab_msg_dequeue(struct virtual_channel *vchan, struct hab_message **msg, * and need empty check again in case the list is empty now due to * dequeue by other threads */ spin_lock_bh(&vchan->rx_lock); hab_spin_lock(&vchan->rx_lock, irqs_disabled); if ((!ret || (ret == -ERESTARTSYS)) && !list_empty(&vchan->rx_list)) { message = list_first_entry(&vchan->rx_list, Loading @@ -99,7 +102,7 @@ hab_msg_dequeue(struct virtual_channel *vchan, struct hab_message **msg, /* no message received, retain the original status */ *rsize = 0; spin_unlock_bh(&vchan->rx_lock); hab_spin_unlock(&vchan->rx_lock, irqs_disabled); *msg = message; return ret; Loading @@ -108,9 +111,11 @@ hab_msg_dequeue(struct virtual_channel *vchan, struct hab_message **msg, static void hab_msg_queue(struct virtual_channel *vchan, struct hab_message *message) { spin_lock_bh(&vchan->rx_lock); int irqs_disabled = irqs_disabled(); hab_spin_lock(&vchan->rx_lock, irqs_disabled); list_add_tail(&message->node, &vchan->rx_list); spin_unlock_bh(&vchan->rx_lock); hab_spin_unlock(&vchan->rx_lock, irqs_disabled); wake_up(&vchan->rx_queue); } Loading @@ -119,11 +124,12 @@ static int hab_export_enqueue(struct virtual_channel *vchan, struct export_desc *exp) { struct uhab_context *ctx = vchan->ctx; int irqs_disabled = irqs_disabled(); spin_lock_bh(&ctx->imp_lock); hab_spin_lock(&ctx->imp_lock, irqs_disabled); list_add_tail(&exp->node, &ctx->imp_whse); ctx->import_total++; spin_unlock_bh(&ctx->imp_lock); hab_spin_unlock(&ctx->imp_lock, irqs_disabled); return 0; } Loading Loading @@ -151,6 +157,7 @@ static int hab_receive_create_export_ack(struct physical_channel *pchan, { struct hab_export_ack_recvd *ack_recvd = kzalloc(sizeof(*ack_recvd), GFP_ATOMIC); int irqs_disabled = irqs_disabled(); if (!ack_recvd) return -ENOMEM; Loading @@ -170,9 +177,9 @@ static int hab_receive_create_export_ack(struct physical_channel *pchan, sizebytes) != sizebytes) return -EIO; spin_lock_bh(&ctx->expq_lock); hab_spin_lock(&ctx->expq_lock, irqs_disabled); list_add_tail(&ack_recvd->node, &ctx->exp_rxq); spin_unlock_bh(&ctx->expq_lock); hab_spin_unlock(&ctx->expq_lock, irqs_disabled); return 0; } Loading drivers/soc/qcom/hab/hab_open.c +10 −7 Original line number Diff line number Diff line /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -46,6 +46,7 @@ int hab_open_request_add(struct physical_channel *pchan, struct hab_device *dev = pchan->habdev; struct hab_open_request *request; struct timeval tv; int irqs_disabled = irqs_disabled(); if (sizebytes > HAB_HEADER_SIZE_MASK) { pr_err("pchan %s request size too large %zd\n", Loading @@ -70,10 +71,11 @@ int hab_open_request_add(struct physical_channel *pchan, tv.tv_usec/1000000; hab_pchan_get(pchan); spin_lock_bh(&dev->openlock); hab_spin_lock(&dev->openlock, irqs_disabled); list_add_tail(&node->node, &dev->openq_list); dev->openq_cnt++; spin_unlock_bh(&dev->openlock); hab_spin_unlock(&dev->openlock, irqs_disabled); return 0; } Loading Loading @@ -192,6 +194,7 @@ int hab_open_receive_cancel(struct physical_channel *pchan, struct hab_open_node *node, *tmp; int bfound = 0; struct timeval tv; int irqs_disabled = irqs_disabled(); if (sizebytes > HAB_HEADER_SIZE_MASK) { pr_err("pchan %s cancel size too large %zd\n", Loading @@ -202,7 +205,7 @@ int hab_open_receive_cancel(struct physical_channel *pchan, if (physical_channel_read(pchan, &data, sizebytes) != sizebytes) return -EIO; spin_lock_bh(&dev->openlock); hab_spin_lock(&dev->openlock, irqs_disabled); list_for_each_entry_safe(node, tmp, &dev->openq_list, node) { request = &node->request; /* check if open request has been serviced or not */ Loading @@ -221,7 +224,7 @@ int hab_open_receive_cancel(struct physical_channel *pchan, break; } } spin_unlock_bh(&dev->openlock); hab_spin_unlock(&dev->openlock, irqs_disabled); if (!bfound) { pr_info("init waiting is in-flight. vcid %x sub %d open %d\n", Loading @@ -244,10 +247,10 @@ int hab_open_receive_cancel(struct physical_channel *pchan, /* put when this node is handled in open path */ hab_pchan_get(pchan); spin_lock_bh(&dev->openlock); hab_spin_lock(&dev->openlock, irqs_disabled); list_add_tail(&node->node, &dev->openq_list); dev->openq_cnt++; spin_unlock_bh(&dev->openlock); hab_spin_unlock(&dev->openlock, irqs_disabled); wake_up_interruptible(&dev->openq); } Loading drivers/soc/qcom/hab/hab_vchan.c +11 −9 Original line number Diff line number Diff line /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -77,16 +77,17 @@ hab_vchan_free(struct kref *ref) struct physical_channel *pchan = vchan->pchan; struct uhab_context *ctx = vchan->ctx; struct virtual_channel *vc, *vc_tmp; int irqs_disabled = irqs_disabled(); spin_lock_bh(&vchan->rx_lock); hab_spin_lock(&vchan->rx_lock, irqs_disabled); list_for_each_entry_safe(message, msg_tmp, &vchan->rx_list, node) { list_del(&message->node); hab_msg_free(message); } spin_unlock_bh(&vchan->rx_lock); hab_spin_unlock(&vchan->rx_lock, irqs_disabled); /* release vchan from pchan. no more msg for this vchan */ write_lock_bh(&pchan->vchans_lock); hab_write_lock(&pchan->vchans_lock, irqs_disabled); list_for_each_entry_safe(vc, vc_tmp, &pchan->vchannels, pnode) { if (vchan == vc) { list_del(&vc->pnode); Loading @@ -95,15 +96,15 @@ hab_vchan_free(struct kref *ref) break; } } write_unlock_bh(&pchan->vchans_lock); hab_write_unlock(&pchan->vchans_lock, irqs_disabled); /* the release vchan from ctx was done earlier in vchan close() */ hab_ctx_put(ctx); /* now ctx is not needed from this vchan's view */ /* release idr at the last so same idr will not be used early */ spin_lock_bh(&pchan->vid_lock); hab_spin_lock(&pchan->vid_lock, irqs_disabled); idr_remove(&pchan->vchan_idr, HAB_VCID_GET_ID(vchan->id)); spin_unlock_bh(&pchan->vid_lock); hab_spin_unlock(&pchan->vid_lock, irqs_disabled); hab_pchan_put(pchan); /* no more need for pchan from this vchan */ Loading @@ -122,8 +123,9 @@ hab_vchan_get(struct physical_channel *pchan, struct hab_header *header) uint32_t session_id = HAB_HEADER_GET_SESSION_ID(*header); size_t sizebytes = HAB_HEADER_GET_SIZE(*header); uint32_t payload_type = HAB_HEADER_GET_TYPE(*header); int irqs_disabled = irqs_disabled(); spin_lock_bh(&pchan->vid_lock); hab_spin_lock(&pchan->vid_lock, irqs_disabled); vchan = idr_find(&pchan->vchan_idr, HAB_VCID_GET_ID(vchan_id)); if (vchan) { if (vchan->session_id != session_id) Loading Loading @@ -162,7 +164,7 @@ hab_vchan_get(struct physical_channel *pchan, struct hab_header *header) vchan = NULL; } } spin_unlock_bh(&pchan->vid_lock); hab_spin_unlock(&pchan->vid_lock, irqs_disabled); return vchan; } Loading Loading
drivers/soc/qcom/hab/ghs_comm.c +9 −7 Original line number Diff line number Diff line /* Copyright (c) 2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -43,19 +43,20 @@ int physical_channel_send(struct physical_channel *pchan, struct ghs_vdev *dev = (struct ghs_vdev *)pchan->hyp_data; GIPC_Result result; uint8_t *msg; int irqs_disabled = irqs_disabled(); spin_lock_bh(&dev->io_lock); hab_spin_lock(&dev->io_lock, irqs_disabled); result = GIPC_PrepareMessage(dev->endpoint, sizebytes+sizeof(*header), (void **)&msg); if (result == GIPC_Full) { spin_unlock_bh(&dev->io_lock); hab_spin_unlock(&dev->io_lock, irqs_disabled); /* need to wait for space! */ pr_err("failed to reserve send msg for %zd bytes\n", sizebytes+sizeof(*header)); return -EBUSY; } else if (result != GIPC_Success) { spin_unlock_bh(&dev->io_lock); hab_spin_unlock(&dev->io_lock, irqs_disabled); pr_err("failed to send due to error %d\n", result); return -ENOMEM; } Loading @@ -77,7 +78,7 @@ int physical_channel_send(struct physical_channel *pchan, result = GIPC_IssueMessage(dev->endpoint, sizebytes+sizeof(*header), header->id_type_size); spin_unlock_bh(&dev->io_lock); hab_spin_unlock(&dev->io_lock, irqs_disabled); if (result != GIPC_Success) { pr_err("send error %d, sz %zd, prot %x\n", result, sizebytes+sizeof(*header), Loading @@ -98,6 +99,7 @@ void physical_channel_rx_dispatch(unsigned long physical_channel) uint32_t events; unsigned long flags; int irqs_disabled = irqs_disabled(); spin_lock_irqsave(&pchan->rxbuf_lock, flags); events = kgipc_dequeue_events(dev->endpoint); Loading @@ -111,7 +113,7 @@ void physical_channel_rx_dispatch(unsigned long physical_channel) dev->name, pchan->vmid_remote); if (events & (GIPC_EVENT_RECEIVEREADY)) { spin_lock_bh(&pchan->rxbuf_lock); hab_spin_lock(&pchan->rxbuf_lock, irqs_disabled); while (1) { dev->read_size = 0; dev->read_offset = 0; Loading @@ -133,7 +135,7 @@ void physical_channel_rx_dispatch(unsigned long physical_channel) result, dev->read_size); break; } spin_unlock_bh(&pchan->rxbuf_lock); hab_spin_unlock(&pchan->rxbuf_lock, irqs_disabled); } if (events & (GIPC_EVENT_SENDREADY)) Loading
drivers/soc/qcom/hab/hab.h +33 −1 Original line number Diff line number Diff line /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -577,6 +577,38 @@ int hab_stat_show_expimp(struct hab_driver *drv, int pid, char *buf, int sz); int hab_stat_init_sub(struct hab_driver *drv); int hab_stat_deinit_sub(struct hab_driver *drv); static inline void hab_spin_lock(spinlock_t *lock, int irqs_disabled) { if (irqs_disabled) spin_lock(lock); else spin_lock_bh(lock); } static inline void hab_spin_unlock(spinlock_t *lock, int irqs_disabled) { if (irqs_disabled) spin_unlock(lock); else spin_unlock_bh(lock); } static inline void hab_write_lock(rwlock_t *lock, int irqs_disabled) { if (irqs_disabled) write_lock(lock); else write_lock_bh(lock); } static inline void hab_write_unlock(rwlock_t *lock, int irqs_disabled) { if (irqs_disabled) write_unlock(lock); else write_unlock_bh(lock); } /* Global singleton HAB instance */ extern struct hab_driver hab_driver; Loading
drivers/soc/qcom/hab/hab_msg.c +18 −11 Original line number Diff line number Diff line /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading @@ -15,10 +15,12 @@ static int hab_rx_queue_empty(struct virtual_channel *vchan) { int ret; int irqs_disabled = irqs_disabled(); spin_lock_bh(&vchan->rx_lock); hab_spin_lock(&vchan->rx_lock, irqs_disabled); ret = list_empty(&vchan->rx_list); spin_unlock_bh(&vchan->rx_lock); hab_spin_unlock(&vchan->rx_lock, irqs_disabled); return ret; } Loading Loading @@ -56,6 +58,7 @@ hab_msg_dequeue(struct virtual_channel *vchan, struct hab_message **msg, int ret = 0; int wait = !(flags & HABMM_SOCKET_RECV_FLAGS_NON_BLOCKING); int interruptible = !(flags & HABMM_SOCKET_RECV_FLAGS_UNINTERRUPTIBLE); int irqs_disabled = irqs_disabled(); if (wait) { if (hab_rx_queue_empty(vchan)) { Loading @@ -75,7 +78,7 @@ hab_msg_dequeue(struct virtual_channel *vchan, struct hab_message **msg, * and need empty check again in case the list is empty now due to * dequeue by other threads */ spin_lock_bh(&vchan->rx_lock); hab_spin_lock(&vchan->rx_lock, irqs_disabled); if ((!ret || (ret == -ERESTARTSYS)) && !list_empty(&vchan->rx_list)) { message = list_first_entry(&vchan->rx_list, Loading @@ -99,7 +102,7 @@ hab_msg_dequeue(struct virtual_channel *vchan, struct hab_message **msg, /* no message received, retain the original status */ *rsize = 0; spin_unlock_bh(&vchan->rx_lock); hab_spin_unlock(&vchan->rx_lock, irqs_disabled); *msg = message; return ret; Loading @@ -108,9 +111,11 @@ hab_msg_dequeue(struct virtual_channel *vchan, struct hab_message **msg, static void hab_msg_queue(struct virtual_channel *vchan, struct hab_message *message) { spin_lock_bh(&vchan->rx_lock); int irqs_disabled = irqs_disabled(); hab_spin_lock(&vchan->rx_lock, irqs_disabled); list_add_tail(&message->node, &vchan->rx_list); spin_unlock_bh(&vchan->rx_lock); hab_spin_unlock(&vchan->rx_lock, irqs_disabled); wake_up(&vchan->rx_queue); } Loading @@ -119,11 +124,12 @@ static int hab_export_enqueue(struct virtual_channel *vchan, struct export_desc *exp) { struct uhab_context *ctx = vchan->ctx; int irqs_disabled = irqs_disabled(); spin_lock_bh(&ctx->imp_lock); hab_spin_lock(&ctx->imp_lock, irqs_disabled); list_add_tail(&exp->node, &ctx->imp_whse); ctx->import_total++; spin_unlock_bh(&ctx->imp_lock); hab_spin_unlock(&ctx->imp_lock, irqs_disabled); return 0; } Loading Loading @@ -151,6 +157,7 @@ static int hab_receive_create_export_ack(struct physical_channel *pchan, { struct hab_export_ack_recvd *ack_recvd = kzalloc(sizeof(*ack_recvd), GFP_ATOMIC); int irqs_disabled = irqs_disabled(); if (!ack_recvd) return -ENOMEM; Loading @@ -170,9 +177,9 @@ static int hab_receive_create_export_ack(struct physical_channel *pchan, sizebytes) != sizebytes) return -EIO; spin_lock_bh(&ctx->expq_lock); hab_spin_lock(&ctx->expq_lock, irqs_disabled); list_add_tail(&ack_recvd->node, &ctx->exp_rxq); spin_unlock_bh(&ctx->expq_lock); hab_spin_unlock(&ctx->expq_lock, irqs_disabled); return 0; } Loading
drivers/soc/qcom/hab/hab_open.c +10 −7 Original line number Diff line number Diff line /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -46,6 +46,7 @@ int hab_open_request_add(struct physical_channel *pchan, struct hab_device *dev = pchan->habdev; struct hab_open_request *request; struct timeval tv; int irqs_disabled = irqs_disabled(); if (sizebytes > HAB_HEADER_SIZE_MASK) { pr_err("pchan %s request size too large %zd\n", Loading @@ -70,10 +71,11 @@ int hab_open_request_add(struct physical_channel *pchan, tv.tv_usec/1000000; hab_pchan_get(pchan); spin_lock_bh(&dev->openlock); hab_spin_lock(&dev->openlock, irqs_disabled); list_add_tail(&node->node, &dev->openq_list); dev->openq_cnt++; spin_unlock_bh(&dev->openlock); hab_spin_unlock(&dev->openlock, irqs_disabled); return 0; } Loading Loading @@ -192,6 +194,7 @@ int hab_open_receive_cancel(struct physical_channel *pchan, struct hab_open_node *node, *tmp; int bfound = 0; struct timeval tv; int irqs_disabled = irqs_disabled(); if (sizebytes > HAB_HEADER_SIZE_MASK) { pr_err("pchan %s cancel size too large %zd\n", Loading @@ -202,7 +205,7 @@ int hab_open_receive_cancel(struct physical_channel *pchan, if (physical_channel_read(pchan, &data, sizebytes) != sizebytes) return -EIO; spin_lock_bh(&dev->openlock); hab_spin_lock(&dev->openlock, irqs_disabled); list_for_each_entry_safe(node, tmp, &dev->openq_list, node) { request = &node->request; /* check if open request has been serviced or not */ Loading @@ -221,7 +224,7 @@ int hab_open_receive_cancel(struct physical_channel *pchan, break; } } spin_unlock_bh(&dev->openlock); hab_spin_unlock(&dev->openlock, irqs_disabled); if (!bfound) { pr_info("init waiting is in-flight. vcid %x sub %d open %d\n", Loading @@ -244,10 +247,10 @@ int hab_open_receive_cancel(struct physical_channel *pchan, /* put when this node is handled in open path */ hab_pchan_get(pchan); spin_lock_bh(&dev->openlock); hab_spin_lock(&dev->openlock, irqs_disabled); list_add_tail(&node->node, &dev->openq_list); dev->openq_cnt++; spin_unlock_bh(&dev->openlock); hab_spin_unlock(&dev->openlock, irqs_disabled); wake_up_interruptible(&dev->openq); } Loading
drivers/soc/qcom/hab/hab_vchan.c +11 −9 Original line number Diff line number Diff line /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -77,16 +77,17 @@ hab_vchan_free(struct kref *ref) struct physical_channel *pchan = vchan->pchan; struct uhab_context *ctx = vchan->ctx; struct virtual_channel *vc, *vc_tmp; int irqs_disabled = irqs_disabled(); spin_lock_bh(&vchan->rx_lock); hab_spin_lock(&vchan->rx_lock, irqs_disabled); list_for_each_entry_safe(message, msg_tmp, &vchan->rx_list, node) { list_del(&message->node); hab_msg_free(message); } spin_unlock_bh(&vchan->rx_lock); hab_spin_unlock(&vchan->rx_lock, irqs_disabled); /* release vchan from pchan. no more msg for this vchan */ write_lock_bh(&pchan->vchans_lock); hab_write_lock(&pchan->vchans_lock, irqs_disabled); list_for_each_entry_safe(vc, vc_tmp, &pchan->vchannels, pnode) { if (vchan == vc) { list_del(&vc->pnode); Loading @@ -95,15 +96,15 @@ hab_vchan_free(struct kref *ref) break; } } write_unlock_bh(&pchan->vchans_lock); hab_write_unlock(&pchan->vchans_lock, irqs_disabled); /* the release vchan from ctx was done earlier in vchan close() */ hab_ctx_put(ctx); /* now ctx is not needed from this vchan's view */ /* release idr at the last so same idr will not be used early */ spin_lock_bh(&pchan->vid_lock); hab_spin_lock(&pchan->vid_lock, irqs_disabled); idr_remove(&pchan->vchan_idr, HAB_VCID_GET_ID(vchan->id)); spin_unlock_bh(&pchan->vid_lock); hab_spin_unlock(&pchan->vid_lock, irqs_disabled); hab_pchan_put(pchan); /* no more need for pchan from this vchan */ Loading @@ -122,8 +123,9 @@ hab_vchan_get(struct physical_channel *pchan, struct hab_header *header) uint32_t session_id = HAB_HEADER_GET_SESSION_ID(*header); size_t sizebytes = HAB_HEADER_GET_SIZE(*header); uint32_t payload_type = HAB_HEADER_GET_TYPE(*header); int irqs_disabled = irqs_disabled(); spin_lock_bh(&pchan->vid_lock); hab_spin_lock(&pchan->vid_lock, irqs_disabled); vchan = idr_find(&pchan->vchan_idr, HAB_VCID_GET_ID(vchan_id)); if (vchan) { if (vchan->session_id != session_id) Loading Loading @@ -162,7 +164,7 @@ hab_vchan_get(struct physical_channel *pchan, struct hab_header *header) vchan = NULL; } } spin_unlock_bh(&pchan->vid_lock); hab_spin_unlock(&pchan->vid_lock, irqs_disabled); return vchan; } Loading