@@ -846,7 +846,7 @@ static long privcmd_ioctl_mmap_resource(struct file *file,
846
846
#ifdef CONFIG_XEN_PRIVCMD_EVENTFD
847
847
/* Irqfd support */
848
848
static struct workqueue_struct * irqfd_cleanup_wq ;
849
- static DEFINE_MUTEX (irqfds_lock );
849
+ static DEFINE_SPINLOCK (irqfds_lock );
850
850
static LIST_HEAD (irqfds_list );
851
851
852
852
struct privcmd_kernel_irqfd {
@@ -910,9 +910,11 @@ irqfd_wakeup(wait_queue_entry_t *wait, unsigned int mode, int sync, void *key)
910
910
irqfd_inject (kirqfd );
911
911
912
912
if (flags & EPOLLHUP ) {
913
- mutex_lock (& irqfds_lock );
913
+ unsigned long flags ;
914
+
915
+ spin_lock_irqsave (& irqfds_lock , flags );
914
916
irqfd_deactivate (kirqfd );
915
- mutex_unlock (& irqfds_lock );
917
+ spin_unlock_irqrestore (& irqfds_lock , flags );
916
918
}
917
919
918
920
return 0 ;
@@ -930,6 +932,7 @@ irqfd_poll_func(struct file *file, wait_queue_head_t *wqh, poll_table *pt)
930
932
static int privcmd_irqfd_assign (struct privcmd_irqfd * irqfd )
931
933
{
932
934
struct privcmd_kernel_irqfd * kirqfd , * tmp ;
935
+ unsigned long flags ;
933
936
__poll_t events ;
934
937
struct fd f ;
935
938
void * dm_op ;
@@ -969,18 +972,18 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd)
969
972
init_waitqueue_func_entry (& kirqfd -> wait , irqfd_wakeup );
970
973
init_poll_funcptr (& kirqfd -> pt , irqfd_poll_func );
971
974
972
- mutex_lock (& irqfds_lock );
975
+ spin_lock_irqsave (& irqfds_lock , flags );
973
976
974
977
list_for_each_entry (tmp , & irqfds_list , list ) {
975
978
if (kirqfd -> eventfd == tmp -> eventfd ) {
976
979
ret = - EBUSY ;
977
- mutex_unlock (& irqfds_lock );
980
+ spin_unlock_irqrestore (& irqfds_lock , flags );
978
981
goto error_eventfd ;
979
982
}
980
983
}
981
984
982
985
list_add_tail (& kirqfd -> list , & irqfds_list );
983
- mutex_unlock (& irqfds_lock );
986
+ spin_unlock_irqrestore (& irqfds_lock , flags );
984
987
985
988
/*
986
989
* Check if there was an event already pending on the eventfd before we
@@ -1012,12 +1015,13 @@ static int privcmd_irqfd_deassign(struct privcmd_irqfd *irqfd)
1012
1015
{
1013
1016
struct privcmd_kernel_irqfd * kirqfd ;
1014
1017
struct eventfd_ctx * eventfd ;
1018
+ unsigned long flags ;
1015
1019
1016
1020
eventfd = eventfd_ctx_fdget (irqfd -> fd );
1017
1021
if (IS_ERR (eventfd ))
1018
1022
return PTR_ERR (eventfd );
1019
1023
1020
- mutex_lock (& irqfds_lock );
1024
+ spin_lock_irqsave (& irqfds_lock , flags );
1021
1025
1022
1026
list_for_each_entry (kirqfd , & irqfds_list , list ) {
1023
1027
if (kirqfd -> eventfd == eventfd ) {
@@ -1026,7 +1030,7 @@ static int privcmd_irqfd_deassign(struct privcmd_irqfd *irqfd)
1026
1030
}
1027
1031
}
1028
1032
1029
- mutex_unlock (& irqfds_lock );
1033
+ spin_unlock_irqrestore (& irqfds_lock , flags );
1030
1034
1031
1035
eventfd_ctx_put (eventfd );
1032
1036
@@ -1074,13 +1078,14 @@ static int privcmd_irqfd_init(void)
1074
1078
static void privcmd_irqfd_exit (void )
1075
1079
{
1076
1080
struct privcmd_kernel_irqfd * kirqfd , * tmp ;
1081
+ unsigned long flags ;
1077
1082
1078
- mutex_lock (& irqfds_lock );
1083
+ spin_lock_irqsave (& irqfds_lock , flags );
1079
1084
1080
1085
list_for_each_entry_safe (kirqfd , tmp , & irqfds_list , list )
1081
1086
irqfd_deactivate (kirqfd );
1082
1087
1083
- mutex_unlock (& irqfds_lock );
1088
+ spin_unlock_irqrestore (& irqfds_lock , flags );
1084
1089
1085
1090
destroy_workqueue (irqfd_cleanup_wq );
1086
1091
}
0 commit comments