forked from TencentOS/TencentOS-kernel
add no_route_to_host_fix switch to turn on/off the fix in bpf mode
Test case 1) conn_reuse_mode = 1 && no_route_to_host_fix==1 result: wrk performance good 2) conn_reuse_mode = 1 && no_route_to_host_fix==0 result: wrk performance bad, packet loss 3) conn_reuse_mode = 0 && no_route_to_host_fix==0 result: wrk performance good. icmp no route to host error 4) conn_reuse_mode = 0 && no_route_to_host_fix==1 result: wrk performance good. no icmp no route to host error Signed-off-by: jianmingfan <jianmingfan@tencent.com>
This commit is contained in:
parent
ef8004f8fe
commit
8ec35911f7
|
|
@ -1704,6 +1704,7 @@ struct bpf_sym_addrs {
|
|||
extern struct bpf_sym_addrs resolve_addrs;
|
||||
extern struct bpf_map *conntrack_map;
|
||||
extern bool bpf_mode_on;
|
||||
extern bool no_route_to_host_fix;
|
||||
extern __be32 major_nic_ip;
|
||||
|
||||
int ip_vs_bpf_put(void);
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ __be32 major_nic_ip;
|
|||
static int ip_local_port_begin;
|
||||
static int ip_local_port_end;
|
||||
struct bpf_map *conntrack_map;
|
||||
|
||||
bool no_route_to_host_fix;
|
||||
struct ip_vs_iter_state {
|
||||
struct seq_net_private p;
|
||||
struct hlist_head *l;
|
||||
|
|
@ -667,6 +667,58 @@ static ssize_t ip_vs_port_write(struct file *file,
|
|||
return count;
|
||||
}
|
||||
|
||||
static ssize_t ip_vs_bpf_fix_write(struct file *file,
|
||||
const char __user *ubuf,
|
||||
size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
char buf[10];
|
||||
int fix;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
if (*ppos > 0) {
|
||||
pr_err("%s %d\n", __func__, __LINE__);
|
||||
return -EFAULT;
|
||||
}
|
||||
if (copy_from_user(buf, ubuf, count)) {
|
||||
pr_err("%s %d\n", __FILE__, __LINE__);
|
||||
return -EFAULT;
|
||||
}
|
||||
if (kstrtoint(buf, 0, &fix) != 0) {
|
||||
pr_err("%s %d\n", __FILE__, __LINE__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (fix != 1 && fix != 0) {
|
||||
pr_err("%s %d\n", __FILE__, __LINE__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
no_route_to_host_fix = fix;
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t ip_vs_bpf_fix_read(struct file *file,
|
||||
char __user *ubuf,
|
||||
size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
int len = 0;
|
||||
char buf[10];
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
if (*ppos > 0) {
|
||||
/* return 0 to sigal eof to user */
|
||||
return 0;
|
||||
}
|
||||
/* snprintf need tail to save null bytes */
|
||||
len = snprintf(buf, sizeof(buf), "0x%d\n", no_route_to_host_fix);
|
||||
if (copy_to_user(ubuf, buf, len))
|
||||
return -EFAULT;
|
||||
/* so next time ppos will be bigger than 0 and return 0 */
|
||||
*ppos = len;
|
||||
return len;
|
||||
}
|
||||
|
||||
static const struct file_operations ip_vs_svc_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = ip_vs_svc_open,
|
||||
|
|
@ -694,6 +746,12 @@ static const struct file_operations ip_vs_port_fops = {
|
|||
.write = ip_vs_port_write,
|
||||
};
|
||||
|
||||
static const struct file_operations ip_vs_bpf_fix_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.read = ip_vs_bpf_fix_read,
|
||||
.write = ip_vs_bpf_fix_write,
|
||||
};
|
||||
|
||||
struct ip_vs_err_map {
|
||||
int errno;
|
||||
const char *name;
|
||||
|
|
@ -774,9 +832,14 @@ int ip_vs_svc_proc_init(struct netns_ipvs *ipvs)
|
|||
if (!proc_create("ip_vs_bpf_stat", S_IRUGO, ipvs->net->proc_net,
|
||||
&ip_vs_bpf_stat_fops))
|
||||
goto out_bpf_stat;
|
||||
if (!proc_create("ip_vs_bpf_fix", 0600,
|
||||
ipvs->net->proc_net, &ip_vs_bpf_fix_fops))
|
||||
goto out_bpf_fix;
|
||||
|
||||
return 0;
|
||||
|
||||
out_bpf_fix:
|
||||
remove_proc_entry("ip_vs_bpf_stat", ipvs->net->proc_net);
|
||||
out_bpf_stat:
|
||||
remove_proc_entry("ip_vs_port_range", ipvs->net->proc_net);
|
||||
out_port_range:
|
||||
|
|
@ -796,5 +859,6 @@ int ip_vs_svc_proc_cleanup(struct netns_ipvs *ipvs)
|
|||
remove_proc_entry("ip_vs_devip", ipvs->net->proc_net);
|
||||
remove_proc_entry("ip_vs_port_range", ipvs->net->proc_net);
|
||||
remove_proc_entry("ip_vs_bpf_stat", ipvs->net->proc_net);
|
||||
remove_proc_entry("ip_vs_bpf_fix", ipvs->net->proc_net);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -270,7 +270,7 @@ static void ip_vs_unlink_bpf(struct ip_vs_conn *cp)
|
|||
return;
|
||||
}
|
||||
|
||||
if (atomic_dec_return(&v->ref) != 0)
|
||||
if (no_route_to_host_fix && atomic_dec_return(&v->ref) != 0)
|
||||
return;
|
||||
reply.sip = cp->dest->addr.ip;
|
||||
reply.sport = cp->dest->port;
|
||||
|
|
@ -1125,10 +1125,12 @@ static bool ip_vs_conn_new_bpf(struct ip_vs_dest *dest,
|
|||
* otherwise, it doesn't reschedule. in such case, the following code
|
||||
* will not run.
|
||||
*/
|
||||
v = map->ops->map_lookup_elem(map, &key);
|
||||
if (v) {
|
||||
atomic_inc(&v->ref);
|
||||
return true;
|
||||
if (no_route_to_host_fix) {
|
||||
v = map->ops->map_lookup_elem(map, &key);
|
||||
if (v) {
|
||||
atomic_inc(&v->ref);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
lip = alloc_localip();
|
||||
|
|
|
|||
|
|
@ -1994,8 +1994,9 @@ ip_vs_in(struct netns_ipvs *ipvs, unsigned int hooknum, struct sk_buff *skb, int
|
|||
* as zero rs may be killed already.
|
||||
* Only enable in bpf mode currently. Shall promote to IPVS mode later.
|
||||
*/
|
||||
if (bpf_mode_on && cp && unlikely(!atomic_read(&cp->dest->weight)) &&
|
||||
is_new_conn(skb, &iph) && !iph.fragoffs) {
|
||||
if (no_route_to_host_fix && bpf_mode_on && cp &&
|
||||
unlikely(!atomic_read(&cp->dest->weight)) &&
|
||||
is_new_conn(skb, &iph) && !iph.fragoffs) {
|
||||
ip_vs_conn_expire_now(cp);
|
||||
__ip_vs_conn_put(cp);
|
||||
cp = NULL;
|
||||
|
|
|
|||
Loading…
Reference in New Issue