IB/rxe: Replace av->network_type with skb->protocol

In the function rxe_init_packet, based on av->network_type, skb->protocol
is set to ipv4 or ipv6. The functions rxe_prepare and rxe_send are called
after the functin rxe_init_packet.  So in these functions,
av->network_type can be replaced with skb->protocol.

The functions are in the xmit fast path. So with skb->protocol, the
performance will be better.

Signed-off-by: Zhu Yanjun <yanjun.zhu@oracle.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
This commit is contained in:
Zhu Yanjun 2019-03-27 05:50:47 -04:00 committed by Jason Gunthorpe
parent 0ac01febd4
commit 08304d7146

View File

@ -338,13 +338,13 @@ static void prepare_ipv6_hdr(struct dst_entry *dst, struct sk_buff *skb,
ip6h->payload_len = htons(skb->len - sizeof(*ip6h)); ip6h->payload_len = htons(skb->len - sizeof(*ip6h));
} }
static int prepare4(struct rxe_pkt_info *pkt, struct sk_buff *skb, static int prepare4(struct rxe_pkt_info *pkt, struct sk_buff *skb)
struct rxe_av *av)
{ {
struct rxe_qp *qp = pkt->qp; struct rxe_qp *qp = pkt->qp;
struct dst_entry *dst; struct dst_entry *dst;
bool xnet = false; bool xnet = false;
__be16 df = htons(IP_DF); __be16 df = htons(IP_DF);
struct rxe_av *av = rxe_get_av(pkt);
struct in_addr *saddr = &av->sgid_addr._sockaddr_in.sin_addr; struct in_addr *saddr = &av->sgid_addr._sockaddr_in.sin_addr;
struct in_addr *daddr = &av->dgid_addr._sockaddr_in.sin_addr; struct in_addr *daddr = &av->dgid_addr._sockaddr_in.sin_addr;
@ -364,11 +364,11 @@ static int prepare4(struct rxe_pkt_info *pkt, struct sk_buff *skb,
return 0; return 0;
} }
static int prepare6(struct rxe_pkt_info *pkt, struct sk_buff *skb, static int prepare6(struct rxe_pkt_info *pkt, struct sk_buff *skb)
struct rxe_av *av)
{ {
struct rxe_qp *qp = pkt->qp; struct rxe_qp *qp = pkt->qp;
struct dst_entry *dst; struct dst_entry *dst;
struct rxe_av *av = rxe_get_av(pkt);
struct in6_addr *saddr = &av->sgid_addr._sockaddr_in6.sin6_addr; struct in6_addr *saddr = &av->sgid_addr._sockaddr_in6.sin6_addr;
struct in6_addr *daddr = &av->dgid_addr._sockaddr_in6.sin6_addr; struct in6_addr *daddr = &av->dgid_addr._sockaddr_in6.sin6_addr;
@ -392,16 +392,15 @@ static int prepare6(struct rxe_pkt_info *pkt, struct sk_buff *skb,
int rxe_prepare(struct rxe_pkt_info *pkt, struct sk_buff *skb, u32 *crc) int rxe_prepare(struct rxe_pkt_info *pkt, struct sk_buff *skb, u32 *crc)
{ {
int err = 0; int err = 0;
struct rxe_av *av = rxe_get_av(pkt);
if (av->network_type == RDMA_NETWORK_IPV4) if (skb->protocol == htons(ETH_P_IP))
err = prepare4(pkt, skb, av); err = prepare4(pkt, skb);
else if (av->network_type == RDMA_NETWORK_IPV6) else if (skb->protocol == htons(ETH_P_IPV6))
err = prepare6(pkt, skb, av); err = prepare6(pkt, skb);
*crc = rxe_icrc_hdr(pkt, skb); *crc = rxe_icrc_hdr(pkt, skb);
if (ether_addr_equal(skb->dev->dev_addr, av->dmac)) if (ether_addr_equal(skb->dev->dev_addr, rxe_get_av(pkt)->dmac))
pkt->mask |= RXE_LOOPBACK_MASK; pkt->mask |= RXE_LOOPBACK_MASK;
return err; return err;
@ -422,23 +421,20 @@ static void rxe_skb_tx_dtor(struct sk_buff *skb)
int rxe_send(struct rxe_pkt_info *pkt, struct sk_buff *skb) int rxe_send(struct rxe_pkt_info *pkt, struct sk_buff *skb)
{ {
struct rxe_av *av;
int err; int err;
av = rxe_get_av(pkt);
skb->destructor = rxe_skb_tx_dtor; skb->destructor = rxe_skb_tx_dtor;
skb->sk = pkt->qp->sk->sk; skb->sk = pkt->qp->sk->sk;
rxe_add_ref(pkt->qp); rxe_add_ref(pkt->qp);
atomic_inc(&pkt->qp->skb_out); atomic_inc(&pkt->qp->skb_out);
if (av->network_type == RDMA_NETWORK_IPV4) { if (skb->protocol == htons(ETH_P_IP)) {
err = ip_local_out(dev_net(skb_dst(skb)->dev), skb->sk, skb); err = ip_local_out(dev_net(skb_dst(skb)->dev), skb->sk, skb);
} else if (av->network_type == RDMA_NETWORK_IPV6) { } else if (skb->protocol == htons(ETH_P_IPV6)) {
err = ip6_local_out(dev_net(skb_dst(skb)->dev), skb->sk, skb); err = ip6_local_out(dev_net(skb_dst(skb)->dev), skb->sk, skb);
} else { } else {
pr_err("Unknown layer 3 protocol: %d\n", av->network_type); pr_err("Unknown layer 3 protocol: %d\n", skb->protocol);
atomic_dec(&pkt->qp->skb_out); atomic_dec(&pkt->qp->skb_out);
rxe_drop_ref(pkt->qp); rxe_drop_ref(pkt->qp);
kfree_skb(skb); kfree_skb(skb);