• Trond Myklebust's avatar
    [PATCH] Teach RPC client to send pages rather than iovecs. · 9f73fdbc
    Trond Myklebust authored
    Stop rpciod from deadlocking against itself in map_new_virtual() on HIGHMEM
    systems. RPC client currently has to keep all pages that are scheduled for
    transmission kmap()ed into an iovec for the entire duration of the call.
    We only actually need to kmap() pages while making the (non-blocking)
    call to sock_sendmsg().
    
    NOTE: When transmitting several pages in one RPC call, sock_sendmsg()
    requires us to kmap() *all* those pages at the same time. Opens for
    deadlocks between rpciod and some other process that also kmaps more
    than 1 page at a time.
    For the TCP case we can solve later by converting to TCP_CORK+sendpage().
    
    include/linux/sunrpc/xdr.h
       Introduce 'struct xdr_buf' in order to allow RPC layer to handle
       pages directly.
    
    include/linux/sunrpc/xprt.h:
       Convert the RPC client send-buffer to the new format.
    
    net/sunrpc/clnt.c
       Initialize the new format RPC send-buffer.
    
    net/sunrpc/sunrpc_syms.c
       Export xdr_encode_pages()
    
    net/sunrpc/xdr.c
       xdr_kmap() kmap()+copy a struct xdr_buf into an iovec array.
       xdr_kunmap() clean up after xdr_kmap().
       xdr_encode_pages() used to inline pages for transmission.
    
    net/sunrpc/xprt.c
       xprt_sendmsg() needs to kmap() the pages into an iovec for transmission.
    
    include/linux/nfs_xdr.h
       struct nfs_writeargs transmits full page information.
       Convert nfs_rpc_ops->write() to send pages.
    
    fs/nfs/write.c
       Adapt to new format nfs_writeargs / nfs_rpc_ops->write()
    
    fs/nfs/proc.c
       Convert nfs_proc_write().
    
    fs/nfs/nfs2xdr.c
       Convert nfs_xdr_writeargs()
    
    fs/nfs/nfs3proc.c
       Convert nfs3_proc_write().
    
    fs/nfs/nfs3xdr.c
       Convert nfs3_xdr_writeargs()
    
    Cheers,
       Trond
    9f73fdbc
nfs3xdr.c 24.7 KB