@@ -826,49 +826,18 @@ static void ep_free(struct eventpoll *ep)
826826 kfree_rcu (ep , rcu );
827827}
828828
829- static void __ep_remove_file (struct eventpoll * ep , struct epitem * epi , struct file * file );
830- static bool __ep_remove_epi (struct eventpoll * ep , struct epitem * epi );
831-
832- /*
833- * Removes a "struct epitem" from the eventpoll RB tree and deallocates
834- * all the associated resources. Must be called with "mtx" held.
835- * If the dying flag is set, do the removal only if force is true.
836- * This prevents ep_clear_and_put() from dropping all the ep references
837- * while running concurrently with eventpoll_release_file().
838- * Returns true if the eventpoll can be disposed.
839- */
840- static bool __ep_remove (struct eventpoll * ep , struct epitem * epi , bool force )
841- {
842- struct file * file = epi -> ffd .file ;
843-
844- lockdep_assert_irqs_enabled ();
845-
846- /*
847- * Removes poll wait queue hooks.
848- */
849- ep_unregister_pollwait (ep , epi );
850-
851- /* Remove the current item from the list of epoll hooks */
852- spin_lock (& file -> f_lock );
853- if (epi -> dying && !force ) {
854- spin_unlock (& file -> f_lock );
855- return false;
856- }
857-
858- __ep_remove_file (ep , epi , file );
859- return __ep_remove_epi (ep , epi );
860- }
861-
862829/*
863830 * Called with &file->f_lock held,
864831 * returns with it released
865832 */
866- static void __ep_remove_file (struct eventpoll * ep , struct epitem * epi , struct file * file )
833+ static void __ep_remove_file (struct eventpoll * ep , struct epitem * epi ,
834+ struct file * file )
867835{
868836 struct epitems_head * to_free = NULL ;
869837 struct hlist_head * head = file -> f_ep ;
870838
871839 lockdep_assert_held (& ep -> mtx );
840+ lockdep_assert_held (& file -> f_lock );
872841
873842 if (hlist_is_singular_node (& epi -> fllink , head )) {
874843 /* See eventpoll_release() for details. */
@@ -915,7 +884,25 @@ static bool __ep_remove_epi(struct eventpoll *ep, struct epitem *epi)
915884 */
916885static void ep_remove_safe (struct eventpoll * ep , struct epitem * epi )
917886{
918- if (__ep_remove (ep , epi , false))
887+ struct file * file = epi -> ffd .file ;
888+
889+ lockdep_assert_irqs_enabled ();
890+ lockdep_assert_held (& ep -> mtx );
891+
892+ ep_unregister_pollwait (ep , epi );
893+
894+ /* sync with eventpoll_release_file() */
895+ if (unlikely (READ_ONCE (epi -> dying )))
896+ return ;
897+
898+ spin_lock (& file -> f_lock );
899+ if (epi -> dying ) {
900+ spin_unlock (& file -> f_lock );
901+ return ;
902+ }
903+ __ep_remove_file (ep , epi , file );
904+
905+ if (__ep_remove_epi (ep , epi ))
919906 WARN_ON_ONCE (ep_refcount_dec_and_test (ep ));
920907}
921908
@@ -1147,7 +1134,7 @@ void eventpoll_release_file(struct file *file)
11471134 spin_lock (& file -> f_lock );
11481135 if (file -> f_ep && file -> f_ep -> first ) {
11491136 epi = hlist_entry (file -> f_ep -> first , struct epitem , fllink );
1150- epi -> dying = true;
1137+ WRITE_ONCE ( epi -> dying , true) ;
11511138 spin_unlock (& file -> f_lock );
11521139
11531140 /*
@@ -1156,7 +1143,13 @@ void eventpoll_release_file(struct file *file)
11561143 */
11571144 ep = epi -> ep ;
11581145 mutex_lock (& ep -> mtx );
1159- dispose = __ep_remove (ep , epi , true);
1146+
1147+ ep_unregister_pollwait (ep , epi );
1148+
1149+ spin_lock (& file -> f_lock );
1150+ __ep_remove_file (ep , epi , file );
1151+ dispose = __ep_remove_epi (ep , epi );
1152+
11601153 mutex_unlock (& ep -> mtx );
11611154
11621155 if (dispose && ep_refcount_dec_and_test (ep ))
0 commit comments