@@ -846,7 +846,7 @@ static long privcmd_ioctl_mmap_resource(struct file *file,
846846#ifdef CONFIG_XEN_PRIVCMD_EVENTFD
847847/* Irqfd support */
848848static struct workqueue_struct * irqfd_cleanup_wq ;
849- static DEFINE_MUTEX (irqfds_lock );
849+ static DEFINE_SPINLOCK (irqfds_lock );
850850static LIST_HEAD (irqfds_list );
851851
852852struct privcmd_kernel_irqfd {
@@ -910,9 +910,11 @@ irqfd_wakeup(wait_queue_entry_t *wait, unsigned int mode, int sync, void *key)
910910 irqfd_inject (kirqfd );
911911
912912 if (flags & EPOLLHUP ) {
913- mutex_lock (& irqfds_lock );
913+ unsigned long flags ;
914+
915+ spin_lock_irqsave (& irqfds_lock , flags );
914916 irqfd_deactivate (kirqfd );
915- mutex_unlock (& irqfds_lock );
917+ spin_unlock_irqrestore (& irqfds_lock , flags );
916918 }
917919
918920 return 0 ;
@@ -930,6 +932,7 @@ irqfd_poll_func(struct file *file, wait_queue_head_t *wqh, poll_table *pt)
930932static int privcmd_irqfd_assign (struct privcmd_irqfd * irqfd )
931933{
932934 struct privcmd_kernel_irqfd * kirqfd , * tmp ;
935+ unsigned long flags ;
933936 __poll_t events ;
934937 struct fd f ;
935938 void * dm_op ;
@@ -969,18 +972,18 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd)
969972 init_waitqueue_func_entry (& kirqfd -> wait , irqfd_wakeup );
970973 init_poll_funcptr (& kirqfd -> pt , irqfd_poll_func );
971974
972- mutex_lock (& irqfds_lock );
975+ spin_lock_irqsave (& irqfds_lock , flags );
973976
974977 list_for_each_entry (tmp , & irqfds_list , list ) {
975978 if (kirqfd -> eventfd == tmp -> eventfd ) {
976979 ret = - EBUSY ;
977- mutex_unlock (& irqfds_lock );
980+ spin_unlock_irqrestore (& irqfds_lock , flags );
978981 goto error_eventfd ;
979982 }
980983 }
981984
982985 list_add_tail (& kirqfd -> list , & irqfds_list );
983- mutex_unlock (& irqfds_lock );
986+ spin_unlock_irqrestore (& irqfds_lock , flags );
984987
985988 /*
986989 * 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)
10121015{
10131016 struct privcmd_kernel_irqfd * kirqfd ;
10141017 struct eventfd_ctx * eventfd ;
1018+ unsigned long flags ;
10151019
10161020 eventfd = eventfd_ctx_fdget (irqfd -> fd );
10171021 if (IS_ERR (eventfd ))
10181022 return PTR_ERR (eventfd );
10191023
1020- mutex_lock (& irqfds_lock );
1024+ spin_lock_irqsave (& irqfds_lock , flags );
10211025
10221026 list_for_each_entry (kirqfd , & irqfds_list , list ) {
10231027 if (kirqfd -> eventfd == eventfd ) {
@@ -1026,7 +1030,7 @@ static int privcmd_irqfd_deassign(struct privcmd_irqfd *irqfd)
10261030 }
10271031 }
10281032
1029- mutex_unlock (& irqfds_lock );
1033+ spin_unlock_irqrestore (& irqfds_lock , flags );
10301034
10311035 eventfd_ctx_put (eventfd );
10321036
@@ -1074,13 +1078,14 @@ static int privcmd_irqfd_init(void)
10741078static void privcmd_irqfd_exit (void )
10751079{
10761080 struct privcmd_kernel_irqfd * kirqfd , * tmp ;
1081+ unsigned long flags ;
10771082
1078- mutex_lock (& irqfds_lock );
1083+ spin_lock_irqsave (& irqfds_lock , flags );
10791084
10801085 list_for_each_entry_safe (kirqfd , tmp , & irqfds_list , list )
10811086 irqfd_deactivate (kirqfd );
10821087
1083- mutex_unlock (& irqfds_lock );
1088+ spin_unlock_irqrestore (& irqfds_lock , flags );
10841089
10851090 destroy_workqueue (irqfd_cleanup_wq );
10861091}
0 commit comments