@@ -1730,29 +1730,31 @@ static int __unregister_kprobe_top(struct kprobe *p)
17301730 if (IS_ERR (ap ))
17311731 return PTR_ERR (ap );
17321732
1733- if (ap == p )
1734- /*
1735- * This probe is an independent(and non-optimized) kprobe
1736- * (not an aggrprobe). Remove from the hash list.
1737- */
1738- goto disarmed ;
1739-
1740- /* Following process expects this probe is an aggrprobe */
1741- WARN_ON (!kprobe_aggrprobe (ap ));
1733+ WARN_ON (ap != p && !kprobe_aggrprobe (ap ));
17421734
1743- if (list_is_singular (& ap -> list ) && kprobe_disarmed (ap ))
1735+ /*
1736+ * If the probe is an independent(and non-optimized) kprobe
1737+ * (not an aggrprobe), the last kprobe on the aggrprobe, or
1738+ * kprobe is already disarmed, just remove from the hash list.
1739+ */
1740+ if (ap == p ||
1741+ (list_is_singular (& ap -> list ) && kprobe_disarmed (ap ))) {
17441742 /*
17451743 * !disarmed could be happen if the probe is under delayed
17461744 * unoptimizing.
17471745 */
1748- goto disarmed ;
1749- else {
1750- /* If disabling probe has special handlers, update aggrprobe */
1751- if (p -> post_handler && !kprobe_gone (p )) {
1752- list_for_each_entry (list_p , & ap -> list , list ) {
1753- if ((list_p != p ) && (list_p -> post_handler ))
1754- goto noclean ;
1755- }
1746+ hlist_del_rcu (& ap -> hlist );
1747+ return 0 ;
1748+ }
1749+
1750+ /* If disabling probe has special handlers, update aggrprobe */
1751+ if (p -> post_handler && !kprobe_gone (p )) {
1752+ list_for_each_entry (list_p , & ap -> list , list ) {
1753+ if ((list_p != p ) && (list_p -> post_handler ))
1754+ break ;
1755+ }
1756+ /* No other probe has post_handler */
1757+ if (list_entry_is_head (list_p , & ap -> list , list )) {
17561758 /*
17571759 * For the kprobe-on-ftrace case, we keep the
17581760 * post_handler setting to identify this aggrprobe
@@ -1761,24 +1763,21 @@ static int __unregister_kprobe_top(struct kprobe *p)
17611763 if (!kprobe_ftrace (ap ))
17621764 ap -> post_handler = NULL ;
17631765 }
1764- noclean :
1766+ }
1767+
1768+ /*
1769+ * Remove from the aggrprobe: this path will do nothing in
1770+ * __unregister_kprobe_bottom().
1771+ */
1772+ list_del_rcu (& p -> list );
1773+ if (!kprobe_disabled (ap ) && !kprobes_all_disarmed )
17651774 /*
1766- * Remove from the aggrprobe: this path will do nothing in
1767- * __unregister_kprobe_bottom() .
1775+ * Try to optimize this probe again, because post
1776+ * handler may have been changed .
17681777 */
1769- list_del_rcu (& p -> list );
1770- if (!kprobe_disabled (ap ) && !kprobes_all_disarmed )
1771- /*
1772- * Try to optimize this probe again, because post
1773- * handler may have been changed.
1774- */
1775- optimize_kprobe (ap );
1776- }
1778+ optimize_kprobe (ap );
17771779 return 0 ;
17781780
1779- disarmed :
1780- hlist_del_rcu (& ap -> hlist );
1781- return 0 ;
17821781}
17831782
17841783static void __unregister_kprobe_bottom (struct kprobe * p )
0 commit comments