The branch main has been updated by afedorov:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=0e6e2c4ef3d1244fa21e7b691e76fdc09f8eacae

commit 0e6e2c4ef3d1244fa21e7b691e76fdc09f8eacae
Author:     Aleksandr Fedorov <[email protected]>
AuthorDate: 2022-09-13 14:15:23 +0000
Commit:     Aleksandr Fedorov <[email protected]>
CommitDate: 2022-09-13 14:20:41 +0000

    netgraph(4): Don't process NGQF_MESG items in NET_EPOCH context.
    
    Netgraph has two main types of message items:
    
    - NGQF_DATA items are used for data processing. This is a hot path that
    should be called from a NET_EPOCH context.
    
    - NGQF_MESG items are used for node configuration. There are many places
    in netgraph(4) where processing the NGQF_MESG item can call sections of code
    that are forbidden in the NET_EPOCH context.
    
    All item types can be queued and then processed using ngthread().
    But ngthread() is unconditionally enter in the NET_EPOCH section for all 
types.
    This causes panic/deadlocks when processing NGQF_MESG elements.
    
    Reported by:    mjg
    Reviewed by:    glebius, vmaffione (mentor)
    Tested by:      mjg, afedorov
    Approved by:    glebius, vmaffione (mentor)
    Sponsored by:   vstack.com
    Differential Revision:  https://reviews.freebsd.org/D36496
---
 sys/netgraph/ng_base.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/sys/netgraph/ng_base.c b/sys/netgraph/ng_base.c
index ac9d55a6f703..092231850f18 100644
--- a/sys/netgraph/ng_base.c
+++ b/sys/netgraph/ng_base.c
@@ -3439,7 +3439,19 @@ ngthread(void *arg)
                        } else {
                                NG_QUEUE_UNLOCK(&node->nd_input_queue);
                                NGI_GET_NODE(item, node); /* zaps stored node */
-                               ng_apply_item(node, item, rw);
+
+                               if ((item->el_flags & NGQF_TYPE) == NGQF_MESG) {
+                                       /*
+                                        * NGQF_MESG items should never be 
processed in
+                                        * NET_EPOCH context. So, temporary 
exit from EPOCH.
+                                        */
+                                       NET_EPOCH_EXIT(et);
+                                       ng_apply_item(node, item, rw);
+                                       NET_EPOCH_ENTER(et);
+                               } else {
+                                       ng_apply_item(node, item, rw);
+                               }
+
                                NG_NODE_UNREF(node);
                        }
                }

Reply via email to