aboutsummaryrefslogtreecommitdiffstats
path: root/net/rxrpc/ar-input.c
diff options
context:
space:
mode:
authorTim Smith <tim@electronghost.co.uk>2014-03-03 18:04:45 -0500
committerDavid Howells <dhowells@redhat.com>2014-03-04 05:36:53 -0500
commit7727640cc3c4d03b6a3cb5bf26d48c72e31403ca (patch)
tree1297fc34c3003a300faa45d57ecd4db15730a5d8 /net/rxrpc/ar-input.c
parente8388eb10371745627d1e538e018cb10ded86aa7 (diff)
af_rxrpc: Keep rxrpc_call pointers in a hashtable
Keep track of rxrpc_call structures in a hashtable so they can be found directly from the network parameters which define the call. This allows incoming packets to be routed directly to a call without walking through hierarchy of peer -> transport -> connection -> call and all the spinlocks that that entailed. Signed-off-by: Tim Smith <tim@electronghost.co.uk> Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'net/rxrpc/ar-input.c')
-rw-r--r--net/rxrpc/ar-input.c177
1 files changed, 73 insertions, 104 deletions
diff --git a/net/rxrpc/ar-input.c b/net/rxrpc/ar-input.c
index e449c675c36a..73742647c135 100644
--- a/net/rxrpc/ar-input.c
+++ b/net/rxrpc/ar-input.c
@@ -523,36 +523,38 @@ protocol_error:
523 * post an incoming packet to the appropriate call/socket to deal with 523 * post an incoming packet to the appropriate call/socket to deal with
524 * - must get rid of the sk_buff, either by freeing it or by queuing it 524 * - must get rid of the sk_buff, either by freeing it or by queuing it
525 */ 525 */
526static void rxrpc_post_packet_to_call(struct rxrpc_connection *conn, 526static void rxrpc_post_packet_to_call(struct rxrpc_call *call,
527 struct sk_buff *skb) 527 struct sk_buff *skb)
528{ 528{
529 struct rxrpc_skb_priv *sp; 529 struct rxrpc_skb_priv *sp;
530 struct rxrpc_call *call;
531 struct rb_node *p;
532 __be32 call_id;
533 530
534 _enter("%p,%p", conn, skb); 531 _enter("%p,%p", call, skb);
535
536 read_lock_bh(&conn->lock);
537 532
538 sp = rxrpc_skb(skb); 533 sp = rxrpc_skb(skb);
539 534
540 /* look at extant calls by channel number first */
541 call = conn->channels[ntohl(sp->hdr.cid) & RXRPC_CHANNELMASK];
542 if (!call || call->call_id != sp->hdr.callNumber)
543 goto call_not_extant;
544
545 _debug("extant call [%d]", call->state); 535 _debug("extant call [%d]", call->state);
546 ASSERTCMP(call->conn, ==, conn);
547 536
548 read_lock(&call->state_lock); 537 read_lock(&call->state_lock);
549 switch (call->state) { 538 switch (call->state) {
550 case RXRPC_CALL_LOCALLY_ABORTED: 539 case RXRPC_CALL_LOCALLY_ABORTED:
551 if (!test_and_set_bit(RXRPC_CALL_ABORT, &call->events)) 540 if (!test_and_set_bit(RXRPC_CALL_ABORT, &call->events)) {
552 rxrpc_queue_call(call); 541 rxrpc_queue_call(call);
542 goto free_unlock;
543 }
553 case RXRPC_CALL_REMOTELY_ABORTED: 544 case RXRPC_CALL_REMOTELY_ABORTED:
554 case RXRPC_CALL_NETWORK_ERROR: 545 case RXRPC_CALL_NETWORK_ERROR:
555 case RXRPC_CALL_DEAD: 546 case RXRPC_CALL_DEAD:
547 goto dead_call;
548 case RXRPC_CALL_COMPLETE:
549 case RXRPC_CALL_CLIENT_FINAL_ACK:
550 /* complete server call */
551 if (call->conn->in_clientflag)
552 goto dead_call;
553 /* resend last packet of a completed call */
554 _debug("final ack again");
555 rxrpc_get_call(call);
556 set_bit(RXRPC_CALL_ACK_FINAL, &call->events);
557 rxrpc_queue_call(call);
556 goto free_unlock; 558 goto free_unlock;
557 default: 559 default:
558 break; 560 break;
@@ -560,7 +562,6 @@ static void rxrpc_post_packet_to_call(struct rxrpc_connection *conn,
560 562
561 read_unlock(&call->state_lock); 563 read_unlock(&call->state_lock);
562 rxrpc_get_call(call); 564 rxrpc_get_call(call);
563 read_unlock_bh(&conn->lock);
564 565
565 if (sp->hdr.type == RXRPC_PACKET_TYPE_DATA && 566 if (sp->hdr.type == RXRPC_PACKET_TYPE_DATA &&
566 sp->hdr.flags & RXRPC_JUMBO_PACKET) 567 sp->hdr.flags & RXRPC_JUMBO_PACKET)
@@ -571,80 +572,16 @@ static void rxrpc_post_packet_to_call(struct rxrpc_connection *conn,
571 rxrpc_put_call(call); 572 rxrpc_put_call(call);
572 goto done; 573 goto done;
573 574
574call_not_extant:
575 /* search the completed calls in case what we're dealing with is
576 * there */
577 _debug("call not extant");
578
579 call_id = sp->hdr.callNumber;
580 p = conn->calls.rb_node;
581 while (p) {
582 call = rb_entry(p, struct rxrpc_call, conn_node);
583
584 if (call_id < call->call_id)
585 p = p->rb_left;
586 else if (call_id > call->call_id)
587 p = p->rb_right;
588 else
589 goto found_completed_call;
590 }
591
592dead_call: 575dead_call:
593 /* it's a either a really old call that we no longer remember or its a
594 * new incoming call */
595 read_unlock_bh(&conn->lock);
596
597 if (sp->hdr.flags & RXRPC_CLIENT_INITIATED &&
598 sp->hdr.seq == cpu_to_be32(1)) {
599 _debug("incoming call");
600 skb_queue_tail(&conn->trans->local->accept_queue, skb);
601 rxrpc_queue_work(&conn->trans->local->acceptor);
602 goto done;
603 }
604
605 _debug("dead call");
606 if (sp->hdr.type != RXRPC_PACKET_TYPE_ABORT) { 576 if (sp->hdr.type != RXRPC_PACKET_TYPE_ABORT) {
607 skb->priority = RX_CALL_DEAD; 577 skb->priority = RX_CALL_DEAD;
608 rxrpc_reject_packet(conn->trans->local, skb); 578 rxrpc_reject_packet(call->conn->trans->local, skb);
609 } 579 goto unlock;
610 goto done;
611
612 /* resend last packet of a completed call
613 * - client calls may have been aborted or ACK'd
614 * - server calls may have been aborted
615 */
616found_completed_call:
617 _debug("completed call");
618
619 if (atomic_read(&call->usage) == 0)
620 goto dead_call;
621
622 /* synchronise any state changes */
623 read_lock(&call->state_lock);
624 ASSERTIFCMP(call->state != RXRPC_CALL_CLIENT_FINAL_ACK,
625 call->state, >=, RXRPC_CALL_COMPLETE);
626
627 if (call->state == RXRPC_CALL_LOCALLY_ABORTED ||
628 call->state == RXRPC_CALL_REMOTELY_ABORTED ||
629 call->state == RXRPC_CALL_DEAD) {
630 read_unlock(&call->state_lock);
631 goto dead_call;
632 } 580 }
633
634 if (call->conn->in_clientflag) {
635 read_unlock(&call->state_lock);
636 goto dead_call; /* complete server call */
637 }
638
639 _debug("final ack again");
640 rxrpc_get_call(call);
641 set_bit(RXRPC_CALL_ACK_FINAL, &call->events);
642 rxrpc_queue_call(call);
643
644free_unlock: 581free_unlock:
645 read_unlock(&call->state_lock);
646 read_unlock_bh(&conn->lock);
647 rxrpc_free_skb(skb); 582 rxrpc_free_skb(skb);
583unlock:
584 read_unlock(&call->state_lock);
648done: 585done:
649 _leave(""); 586 _leave("");
650} 587}
@@ -663,17 +600,42 @@ static void rxrpc_post_packet_to_conn(struct rxrpc_connection *conn,
663 rxrpc_queue_conn(conn); 600 rxrpc_queue_conn(conn);
664} 601}
665 602
603static struct rxrpc_connection *rxrpc_conn_from_local(struct rxrpc_local *local,
604 struct sk_buff *skb,
605 struct rxrpc_skb_priv *sp)
606{
607 struct rxrpc_peer *peer;
608 struct rxrpc_transport *trans;
609 struct rxrpc_connection *conn;
610
611 peer = rxrpc_find_peer(local, ip_hdr(skb)->saddr,
612 udp_hdr(skb)->source);
613 if (IS_ERR(peer))
614 goto cant_find_conn;
615
616 trans = rxrpc_find_transport(local, peer);
617 rxrpc_put_peer(peer);
618 if (!trans)
619 goto cant_find_conn;
620
621 conn = rxrpc_find_connection(trans, &sp->hdr);
622 rxrpc_put_transport(trans);
623 if (!conn)
624 goto cant_find_conn;
625
626 return conn;
627cant_find_conn:
628 return NULL;
629}
630
666/* 631/*
667 * handle data received on the local endpoint 632 * handle data received on the local endpoint
668 * - may be called in interrupt context 633 * - may be called in interrupt context
669 */ 634 */
670void rxrpc_data_ready(struct sock *sk, int count) 635void rxrpc_data_ready(struct sock *sk, int count)
671{ 636{
672 struct rxrpc_connection *conn;
673 struct rxrpc_transport *trans;
674 struct rxrpc_skb_priv *sp; 637 struct rxrpc_skb_priv *sp;
675 struct rxrpc_local *local; 638 struct rxrpc_local *local;
676 struct rxrpc_peer *peer;
677 struct sk_buff *skb; 639 struct sk_buff *skb;
678 int ret; 640 int ret;
679 641
@@ -748,27 +710,34 @@ void rxrpc_data_ready(struct sock *sk, int count)
748 (sp->hdr.callNumber == 0 || sp->hdr.seq == 0)) 710 (sp->hdr.callNumber == 0 || sp->hdr.seq == 0))
749 goto bad_message; 711 goto bad_message;
750 712
751 peer = rxrpc_find_peer(local, ip_hdr(skb)->saddr, udp_hdr(skb)->source); 713 if (sp->hdr.callNumber == 0) {
752 if (IS_ERR(peer)) 714 /* This is a connection-level packet. These should be
753 goto cant_route_call; 715 * fairly rare, so the extra overhead of looking them up the
754 716 * old-fashioned way doesn't really hurt */
755 trans = rxrpc_find_transport(local, peer); 717 struct rxrpc_connection *conn;
756 rxrpc_put_peer(peer);
757 if (!trans)
758 goto cant_route_call;
759
760 conn = rxrpc_find_connection(trans, &sp->hdr);
761 rxrpc_put_transport(trans);
762 if (!conn)
763 goto cant_route_call;
764 718
765 _debug("CONN %p {%d}", conn, conn->debug_id); 719 conn = rxrpc_conn_from_local(local, skb, sp);
720 if (!conn)
721 goto cant_route_call;
766 722
767 if (sp->hdr.callNumber == 0) 723 _debug("CONN %p {%d}", conn, conn->debug_id);
768 rxrpc_post_packet_to_conn(conn, skb); 724 rxrpc_post_packet_to_conn(conn, skb);
769 else 725 rxrpc_put_connection(conn);
770 rxrpc_post_packet_to_call(conn, skb); 726 } else {
771 rxrpc_put_connection(conn); 727 struct rxrpc_call *call;
728 u8 in_clientflag = 0;
729
730 if (sp->hdr.flags & RXRPC_CLIENT_INITIATED)
731 in_clientflag = RXRPC_CLIENT_INITIATED;
732 call = rxrpc_find_call_hash(in_clientflag, sp->hdr.cid,
733 sp->hdr.callNumber, sp->hdr.epoch,
734 sp->hdr.serviceId, local, AF_INET,
735 (u8 *)&ip_hdr(skb)->saddr);
736 if (call)
737 rxrpc_post_packet_to_call(call, skb);
738 else
739 goto cant_route_call;
740 }
772 rxrpc_put_local(local); 741 rxrpc_put_local(local);
773 return; 742 return;
774 743