• J
    svcrpc: fix wspace-checking race · 9c335c0b
    J. Bruce Fields 提交于
    We call svc_xprt_enqueue() after something happens which we think may
    require handling from a server thread.  To avoid such events being lost,
    svc_xprt_enqueue() must guarantee that there will be a svc_serv() call
    from a server thread following any such event.  It does that by either
    waking up a server thread itself, or checking that XPT_BUSY is set (in
    which case somebody else is doing it).
    
    But the check of XPT_BUSY could occur just as someone finishes
    processing some other event, and just before they clear XPT_BUSY.
    
    Therefore it's important not to clear XPT_BUSY without subsequently
    doing another svc_export_enqueue() to check whether the xprt should be
    requeued.
    
    The xpo_wspace() check in svc_xprt_enqueue() breaks this rule, allowing
    an event to be missed in situations like:
    
    	data arrives
    	call svc_tcp_data_ready():
    	call svc_xprt_enqueue():
    	set BUSY
    	find no write space
    				svc_reserve():
    				free up write space
    				call svc_enqueue():
    				test BUSY
    	clear BUSY
    
    So, instead, check wspace in the same places that the state flags are
    checked: before taking BUSY, and in svc_receive().
    Signed-off-by: NJ. Bruce Fields <bfields@redhat.com>
    9c335c0b
svc_xprt.c 33.1 KB