Commit 1d861aa4b3fb08822055345f480850205ffe6170
1 parent
16d1839907
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
inet: Minimize use of cached route inetpeer.
Only use it in the absolutely required cases: 1) COW'ing metrics 2) ipv4 PMTU 3) ipv4 redirects Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 5 changed files with 35 additions and 22 deletions Side-by-side Diff
net/ipv4/icmp.c
... | ... | @@ -254,9 +254,10 @@ |
254 | 254 | |
255 | 255 | /* Limit if icmp type is enabled in ratemask. */ |
256 | 256 | if ((1 << type) & net->ipv4.sysctl_icmp_ratemask) { |
257 | - struct inet_peer *peer = rt_get_peer_create(rt, fl4->daddr); | |
257 | + struct inet_peer *peer = inet_getpeer_v4(net->ipv4.peers, fl4->daddr, 1); | |
258 | 258 | rc = inet_peer_xrlim_allow(peer, |
259 | 259 | net->ipv4.sysctl_icmp_ratelimit); |
260 | + inet_putpeer(peer); | |
260 | 261 | } |
261 | 262 | out: |
262 | 263 | return rc; |
net/ipv4/route.c
... | ... | @@ -1289,21 +1289,16 @@ |
1289 | 1289 | |
1290 | 1290 | void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more) |
1291 | 1291 | { |
1292 | - struct rtable *rt = (struct rtable *) dst; | |
1292 | + struct net *net = dev_net(dst->dev); | |
1293 | + struct inet_peer *peer; | |
1293 | 1294 | |
1294 | - if (rt && !(rt->dst.flags & DST_NOPEER)) { | |
1295 | - struct inet_peer *peer = rt_get_peer_create(rt, rt->rt_dst); | |
1295 | + peer = inet_getpeer_v4(net->ipv4.peers, iph->daddr, 1); | |
1296 | + if (peer) { | |
1297 | + iph->id = htons(inet_getid(peer, more)); | |
1298 | + inet_putpeer(peer); | |
1299 | + return; | |
1300 | + } | |
1296 | 1301 | |
1297 | - /* If peer is attached to destination, it is never detached, | |
1298 | - so that we need not to grab a lock to dereference it. | |
1299 | - */ | |
1300 | - if (peer) { | |
1301 | - iph->id = htons(inet_getid(peer, more)); | |
1302 | - return; | |
1303 | - } | |
1304 | - } else if (!rt) | |
1305 | - pr_debug("rt_bind_peer(0) @%p\n", __builtin_return_address(0)); | |
1306 | - | |
1307 | 1302 | ip_select_fb_ident(iph); |
1308 | 1303 | } |
1309 | 1304 | EXPORT_SYMBOL(__ip_select_ident); |
... | ... | @@ -1492,6 +1487,7 @@ |
1492 | 1487 | struct rtable *rt = skb_rtable(skb); |
1493 | 1488 | struct in_device *in_dev; |
1494 | 1489 | struct inet_peer *peer; |
1490 | + struct net *net; | |
1495 | 1491 | int log_martians; |
1496 | 1492 | |
1497 | 1493 | rcu_read_lock(); |
... | ... | @@ -1503,7 +1499,8 @@ |
1503 | 1499 | log_martians = IN_DEV_LOG_MARTIANS(in_dev); |
1504 | 1500 | rcu_read_unlock(); |
1505 | 1501 | |
1506 | - peer = rt_get_peer_create(rt, rt->rt_dst); | |
1502 | + net = dev_net(rt->dst.dev); | |
1503 | + peer = inet_getpeer_v4(net->ipv4.peers, ip_hdr(skb)->saddr, 1); | |
1507 | 1504 | if (!peer) { |
1508 | 1505 | icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, rt->rt_gateway); |
1509 | 1506 | return; |
... | ... | @@ -1520,7 +1517,7 @@ |
1520 | 1517 | */ |
1521 | 1518 | if (peer->rate_tokens >= ip_rt_redirect_number) { |
1522 | 1519 | peer->rate_last = jiffies; |
1523 | - return; | |
1520 | + goto out_put_peer; | |
1524 | 1521 | } |
1525 | 1522 | |
1526 | 1523 | /* Check for load limit; set rate_last to the latest sent |
... | ... | @@ -1541,6 +1538,8 @@ |
1541 | 1538 | &rt->rt_dst, &rt->rt_gateway); |
1542 | 1539 | #endif |
1543 | 1540 | } |
1541 | +out_put_peer: | |
1542 | + inet_putpeer(peer); | |
1544 | 1543 | } |
1545 | 1544 | |
1546 | 1545 | static int ip_error(struct sk_buff *skb) |
... | ... | @@ -1583,7 +1582,7 @@ |
1583 | 1582 | break; |
1584 | 1583 | } |
1585 | 1584 | |
1586 | - peer = rt_get_peer_create(rt, rt->rt_dst); | |
1585 | + peer = inet_getpeer_v4(net->ipv4.peers, ip_hdr(skb)->saddr, 1); | |
1587 | 1586 | |
1588 | 1587 | send = true; |
1589 | 1588 | if (peer) { |
... | ... | @@ -1596,6 +1595,7 @@ |
1596 | 1595 | peer->rate_tokens -= ip_rt_error_cost; |
1597 | 1596 | else |
1598 | 1597 | send = false; |
1598 | + inet_putpeer(peer); | |
1599 | 1599 | } |
1600 | 1600 | if (send) |
1601 | 1601 | icmp_send(skb, ICMP_DEST_UNREACH, code, 0); |
net/ipv6/icmp.c
... | ... | @@ -194,8 +194,10 @@ |
194 | 194 | if (rt->rt6i_dst.plen < 128) |
195 | 195 | tmo >>= ((128 - rt->rt6i_dst.plen)>>5); |
196 | 196 | |
197 | - peer = rt6_get_peer_create(rt); | |
197 | + peer = inet_getpeer_v6(net->ipv6.peers, &rt->rt6i_dst.addr, 1); | |
198 | 198 | res = inet_peer_xrlim_allow(peer, tmo); |
199 | + if (peer) | |
200 | + inet_putpeer(peer); | |
199 | 201 | } |
200 | 202 | dst_release(dst); |
201 | 203 | return res; |
net/ipv6/ip6_output.c
... | ... | @@ -466,13 +466,15 @@ |
466 | 466 | else |
467 | 467 | target = &hdr->daddr; |
468 | 468 | |
469 | - peer = rt6_get_peer_create(rt); | |
469 | + peer = inet_getpeer_v6(net->ipv6.peers, &rt->rt6i_dst.addr, 1); | |
470 | 470 | |
471 | 471 | /* Limit redirects both by destination (here) |
472 | 472 | and by source (inside ndisc_send_redirect) |
473 | 473 | */ |
474 | 474 | if (inet_peer_xrlim_allow(peer, 1*HZ)) |
475 | 475 | ndisc_send_redirect(skb, target); |
476 | + if (peer) | |
477 | + inet_putpeer(peer); | |
476 | 478 | } else { |
477 | 479 | int addrtype = ipv6_addr_type(&hdr->saddr); |
478 | 480 | |
479 | 481 | |
480 | 482 | |
... | ... | @@ -592,10 +594,14 @@ |
592 | 594 | int old, new; |
593 | 595 | |
594 | 596 | if (rt && !(rt->dst.flags & DST_NOPEER)) { |
595 | - struct inet_peer *peer = rt6_get_peer_create(rt); | |
597 | + struct inet_peer *peer; | |
598 | + struct net *net; | |
596 | 599 | |
600 | + net = dev_net(rt->dst.dev); | |
601 | + peer = inet_getpeer_v6(net->ipv6.peers, &rt->rt6i_dst.addr, 1); | |
597 | 602 | if (peer) { |
598 | 603 | fhdr->identification = htonl(inet_getid(peer, 0)); |
604 | + inet_putpeer(peer); | |
599 | 605 | return; |
600 | 606 | } |
601 | 607 | } |
net/ipv6/ndisc.c
... | ... | @@ -1486,6 +1486,7 @@ |
1486 | 1486 | int rd_len; |
1487 | 1487 | int err; |
1488 | 1488 | u8 ha_buf[MAX_ADDR_LEN], *ha = NULL; |
1489 | + bool ret; | |
1489 | 1490 | |
1490 | 1491 | if (ipv6_get_lladdr(dev, &saddr_buf, IFA_F_TENTATIVE)) { |
1491 | 1492 | ND_PRINTK(2, warn, "Redirect: no link-local address on %s\n", |
... | ... | @@ -1519,8 +1520,11 @@ |
1519 | 1520 | "Redirect: destination is not a neighbour\n"); |
1520 | 1521 | goto release; |
1521 | 1522 | } |
1522 | - peer = rt6_get_peer_create(rt); | |
1523 | - if (!inet_peer_xrlim_allow(peer, 1*HZ)) | |
1523 | + peer = inet_getpeer_v6(net->ipv6.peers, &rt->rt6i_dst.addr, 1); | |
1524 | + ret = inet_peer_xrlim_allow(peer, 1*HZ); | |
1525 | + if (peer) | |
1526 | + inet_putpeer(peer); | |
1527 | + if (!ret) | |
1524 | 1528 | goto release; |
1525 | 1529 | |
1526 | 1530 | if (dev->addr_len) { |