@@ -753,7 +753,7 @@ static void
753
753
xprt_schedule_autodisconnect (struct rpc_xprt * xprt )
754
754
__must_hold (& xprt - > transport_lock )
755
755
{
756
- if (list_empty (& xprt -> recv_queue ) && xprt_has_timer (xprt ))
756
+ if (RB_EMPTY_ROOT (& xprt -> recv_queue ) && xprt_has_timer (xprt ))
757
757
mod_timer (& xprt -> timer , xprt -> last_used + xprt -> idle_timeout );
758
758
}
759
759
@@ -763,7 +763,7 @@ xprt_init_autodisconnect(struct timer_list *t)
763
763
struct rpc_xprt * xprt = from_timer (xprt , t , timer );
764
764
765
765
spin_lock (& xprt -> transport_lock );
766
- if (!list_empty (& xprt -> recv_queue ))
766
+ if (!RB_EMPTY_ROOT (& xprt -> recv_queue ))
767
767
goto out_abort ;
768
768
/* Reset xprt->last_used to avoid connect/autodisconnect cycling */
769
769
xprt -> last_used = jiffies ;
@@ -880,6 +880,75 @@ static void xprt_connect_status(struct rpc_task *task)
880
880
}
881
881
}
882
882
883
+ enum xprt_xid_rb_cmp {
884
+ XID_RB_EQUAL ,
885
+ XID_RB_LEFT ,
886
+ XID_RB_RIGHT ,
887
+ };
888
+ static enum xprt_xid_rb_cmp
889
+ xprt_xid_cmp (__be32 xid1 , __be32 xid2 )
890
+ {
891
+ if (xid1 == xid2 )
892
+ return XID_RB_EQUAL ;
893
+ if ((__force u32 )xid1 < (__force u32 )xid2 )
894
+ return XID_RB_LEFT ;
895
+ return XID_RB_RIGHT ;
896
+ }
897
+
898
+ static struct rpc_rqst *
899
+ xprt_request_rb_find (struct rpc_xprt * xprt , __be32 xid )
900
+ {
901
+ struct rb_node * n = xprt -> recv_queue .rb_node ;
902
+ struct rpc_rqst * req ;
903
+
904
+ while (n != NULL ) {
905
+ req = rb_entry (n , struct rpc_rqst , rq_recv );
906
+ switch (xprt_xid_cmp (xid , req -> rq_xid )) {
907
+ case XID_RB_LEFT :
908
+ n = n -> rb_left ;
909
+ break ;
910
+ case XID_RB_RIGHT :
911
+ n = n -> rb_right ;
912
+ break ;
913
+ case XID_RB_EQUAL :
914
+ return req ;
915
+ }
916
+ }
917
+ return NULL ;
918
+ }
919
+
920
+ static void
921
+ xprt_request_rb_insert (struct rpc_xprt * xprt , struct rpc_rqst * new )
922
+ {
923
+ struct rb_node * * p = & xprt -> recv_queue .rb_node ;
924
+ struct rb_node * n = NULL ;
925
+ struct rpc_rqst * req ;
926
+
927
+ while (* p != NULL ) {
928
+ n = * p ;
929
+ req = rb_entry (n , struct rpc_rqst , rq_recv );
930
+ switch (xprt_xid_cmp (new -> rq_xid , req -> rq_xid )) {
931
+ case XID_RB_LEFT :
932
+ p = & n -> rb_left ;
933
+ break ;
934
+ case XID_RB_RIGHT :
935
+ p = & n -> rb_right ;
936
+ break ;
937
+ case XID_RB_EQUAL :
938
+ WARN_ON_ONCE (new != req );
939
+ return ;
940
+ }
941
+ }
942
+ rb_link_node (& new -> rq_recv , n , p );
943
+ rb_insert_color (& new -> rq_recv , & xprt -> recv_queue );
944
+ }
945
+
946
+ static void
947
+ xprt_request_rb_remove (struct rpc_xprt * xprt , struct rpc_rqst * req )
948
+ {
949
+ rb_erase (& req -> rq_recv , & xprt -> recv_queue );
950
+ }
951
+
883
952
/**
884
953
* xprt_lookup_rqst - find an RPC request corresponding to an XID
885
954
* @xprt: transport on which the original request was transmitted
@@ -891,12 +960,12 @@ struct rpc_rqst *xprt_lookup_rqst(struct rpc_xprt *xprt, __be32 xid)
891
960
{
892
961
struct rpc_rqst * entry ;
893
962
894
- list_for_each_entry ( entry , & xprt -> recv_queue , rq_recv )
895
- if (entry -> rq_xid == xid ) {
896
- trace_xprt_lookup_rqst (xprt , xid , 0 );
897
- entry -> rq_rtt = ktime_sub (ktime_get (), entry -> rq_xtime );
898
- return entry ;
899
- }
963
+ entry = xprt_request_rb_find ( xprt , xid );
964
+ if (entry != NULL ) {
965
+ trace_xprt_lookup_rqst (xprt , xid , 0 );
966
+ entry -> rq_rtt = ktime_sub (ktime_get (), entry -> rq_xtime );
967
+ return entry ;
968
+ }
900
969
901
970
dprintk ("RPC: xprt_lookup_rqst did not find xid %08x\n" ,
902
971
ntohl (xid ));
@@ -981,7 +1050,7 @@ xprt_request_enqueue_receive(struct rpc_task *task)
981
1050
sizeof (req -> rq_private_buf ));
982
1051
983
1052
/* Add request to the receive list */
984
- list_add_tail ( & req -> rq_recv , & xprt -> recv_queue );
1053
+ xprt_request_rb_insert ( xprt , req );
985
1054
set_bit (RPC_TASK_NEED_RECV , & task -> tk_runstate );
986
1055
spin_unlock (& xprt -> queue_lock );
987
1056
@@ -999,8 +1068,10 @@ xprt_request_enqueue_receive(struct rpc_task *task)
999
1068
static void
1000
1069
xprt_request_dequeue_receive_locked (struct rpc_task * task )
1001
1070
{
1071
+ struct rpc_rqst * req = task -> tk_rqstp ;
1072
+
1002
1073
if (test_and_clear_bit (RPC_TASK_NEED_RECV , & task -> tk_runstate ))
1003
- list_del ( & task -> tk_rqstp -> rq_recv );
1074
+ xprt_request_rb_remove ( req -> rq_xprt , req );
1004
1075
}
1005
1076
1006
1077
/**
@@ -1711,7 +1782,7 @@ static void xprt_init(struct rpc_xprt *xprt, struct net *net)
1711
1782
spin_lock_init (& xprt -> queue_lock );
1712
1783
1713
1784
INIT_LIST_HEAD (& xprt -> free );
1714
- INIT_LIST_HEAD ( & xprt -> recv_queue ) ;
1785
+ xprt -> recv_queue = RB_ROOT ;
1715
1786
INIT_LIST_HEAD (& xprt -> xmit_queue );
1716
1787
#if defined(CONFIG_SUNRPC_BACKCHANNEL )
1717
1788
spin_lock_init (& xprt -> bc_pa_lock );
0 commit comments