Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf

Alexei Starovoitov says:

====================
pull-request: bpf 2019-10-12

The following pull-request contains BPF updates for your *net* tree.

The main changes are:

1) a bunch of small fixes. Nothing critical.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2019-10-12 11:21:56 -07:00
commit 8caf8a91f3
11 changed files with 95 additions and 34 deletions

View File

@ -305,9 +305,8 @@ out:
} }
EXPORT_SYMBOL(xsk_umem_consume_tx); EXPORT_SYMBOL(xsk_umem_consume_tx);
static int xsk_zc_xmit(struct sock *sk) static int xsk_zc_xmit(struct xdp_sock *xs)
{ {
struct xdp_sock *xs = xdp_sk(sk);
struct net_device *dev = xs->dev; struct net_device *dev = xs->dev;
return dev->netdev_ops->ndo_xsk_wakeup(dev, xs->queue_id, return dev->netdev_ops->ndo_xsk_wakeup(dev, xs->queue_id,
@ -327,11 +326,10 @@ static void xsk_destruct_skb(struct sk_buff *skb)
sock_wfree(skb); sock_wfree(skb);
} }
static int xsk_generic_xmit(struct sock *sk, struct msghdr *m, static int xsk_generic_xmit(struct sock *sk)
size_t total_len)
{ {
u32 max_batch = TX_BATCH_SIZE;
struct xdp_sock *xs = xdp_sk(sk); struct xdp_sock *xs = xdp_sk(sk);
u32 max_batch = TX_BATCH_SIZE;
bool sent_frame = false; bool sent_frame = false;
struct xdp_desc desc; struct xdp_desc desc;
struct sk_buff *skb; struct sk_buff *skb;
@ -394,6 +392,18 @@ out:
return err; return err;
} }
static int __xsk_sendmsg(struct sock *sk)
{
struct xdp_sock *xs = xdp_sk(sk);
if (unlikely(!(xs->dev->flags & IFF_UP)))
return -ENETDOWN;
if (unlikely(!xs->tx))
return -ENOBUFS;
return xs->zc ? xsk_zc_xmit(xs) : xsk_generic_xmit(sk);
}
static int xsk_sendmsg(struct socket *sock, struct msghdr *m, size_t total_len) static int xsk_sendmsg(struct socket *sock, struct msghdr *m, size_t total_len)
{ {
bool need_wait = !(m->msg_flags & MSG_DONTWAIT); bool need_wait = !(m->msg_flags & MSG_DONTWAIT);
@ -402,21 +412,18 @@ static int xsk_sendmsg(struct socket *sock, struct msghdr *m, size_t total_len)
if (unlikely(!xsk_is_bound(xs))) if (unlikely(!xsk_is_bound(xs)))
return -ENXIO; return -ENXIO;
if (unlikely(!(xs->dev->flags & IFF_UP))) if (unlikely(need_wait))
return -ENETDOWN;
if (unlikely(!xs->tx))
return -ENOBUFS;
if (need_wait)
return -EOPNOTSUPP; return -EOPNOTSUPP;
return (xs->zc) ? xsk_zc_xmit(sk) : xsk_generic_xmit(sk, m, total_len); return __xsk_sendmsg(sk);
} }
static unsigned int xsk_poll(struct file *file, struct socket *sock, static unsigned int xsk_poll(struct file *file, struct socket *sock,
struct poll_table_struct *wait) struct poll_table_struct *wait)
{ {
unsigned int mask = datagram_poll(file, sock, wait); unsigned int mask = datagram_poll(file, sock, wait);
struct xdp_sock *xs = xdp_sk(sock->sk); struct sock *sk = sock->sk;
struct xdp_sock *xs = xdp_sk(sk);
struct net_device *dev; struct net_device *dev;
struct xdp_umem *umem; struct xdp_umem *umem;
@ -426,9 +433,14 @@ static unsigned int xsk_poll(struct file *file, struct socket *sock,
dev = xs->dev; dev = xs->dev;
umem = xs->umem; umem = xs->umem;
if (umem->need_wakeup) if (umem->need_wakeup) {
dev->netdev_ops->ndo_xsk_wakeup(dev, xs->queue_id, if (dev->netdev_ops->ndo_xsk_wakeup)
umem->need_wakeup); dev->netdev_ops->ndo_xsk_wakeup(dev, xs->queue_id,
umem->need_wakeup);
else
/* Poll needs to drive Tx also in copy mode */
__xsk_sendmsg(sk);
}
if (xs->rx && !xskq_empty_desc(xs->rx)) if (xs->rx && !xskq_empty_desc(xs->rx))
mask |= POLLIN | POLLRDNORM; mask |= POLLIN | POLLRDNORM;

View File

@ -3,7 +3,8 @@
#ifndef __ASM_GOTO_WORKAROUND_H #ifndef __ASM_GOTO_WORKAROUND_H
#define __ASM_GOTO_WORKAROUND_H #define __ASM_GOTO_WORKAROUND_H
/* this will bring in asm_volatile_goto macro definition /*
* This will bring in asm_volatile_goto and asm_inline macro definitions
* if enabled by compiler and config options. * if enabled by compiler and config options.
*/ */
#include <linux/types.h> #include <linux/types.h>
@ -13,5 +14,15 @@
#define asm_volatile_goto(x...) asm volatile("invalid use of asm_volatile_goto") #define asm_volatile_goto(x...) asm volatile("invalid use of asm_volatile_goto")
#endif #endif
/*
* asm_inline is defined as asm __inline in "include/linux/compiler_types.h"
* if supported by the kernel's CC (i.e CONFIG_CC_HAS_ASM_INLINE) which is not
* supported by CLANG.
*/
#ifdef asm_inline
#undef asm_inline
#define asm_inline asm
#endif
#define volatile(x...) volatile("") #define volatile(x...) volatile("")
#endif #endif

View File

@ -13,6 +13,7 @@
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <linux/perf_event.h>
#include "libbpf.h" #include "libbpf.h"
#include "bpf_load.h" #include "bpf_load.h"

View File

@ -12,7 +12,11 @@ INSTALL ?= install
CFLAGS += -Wall -O2 CFLAGS += -Wall -O2
CFLAGS += -D__EXPORTED_HEADERS__ -I$(srctree)/include/uapi -I$(srctree)/include CFLAGS += -D__EXPORTED_HEADERS__ -I$(srctree)/include/uapi -I$(srctree)/include
ifeq ($(srctree),) # This will work when bpf is built in tools env. where srctree
# isn't set and when invoked from selftests build, where srctree
# is set to ".". building_out_of_srctree is undefined for in srctree
# builds
ifndef building_out_of_srctree
srctree := $(patsubst %/,%,$(dir $(CURDIR))) srctree := $(patsubst %/,%,$(dir $(CURDIR)))
srctree := $(patsubst %/,%,$(dir $(srctree))) srctree := $(patsubst %/,%,$(dir $(srctree)))
endif endif

View File

@ -8,7 +8,11 @@ LIBBPF_MAJOR_VERSION := $(firstword $(subst ., ,$(LIBBPF_VERSION)))
MAKEFLAGS += --no-print-directory MAKEFLAGS += --no-print-directory
ifeq ($(srctree),) # This will work when bpf is built in tools env. where srctree
# isn't set and when invoked from selftests build, where srctree
# is a ".". building_out_of_srctree is undefined for in srctree
# builds
ifndef building_out_of_srctree
srctree := $(patsubst %/,%,$(dir $(CURDIR))) srctree := $(patsubst %/,%,$(dir $(CURDIR)))
srctree := $(patsubst %/,%,$(dir $(srctree))) srctree := $(patsubst %/,%,$(dir $(srctree)))
srctree := $(patsubst %/,%,$(dir $(srctree))) srctree := $(patsubst %/,%,$(dir $(srctree)))
@ -110,6 +114,9 @@ override CFLAGS += $(INCLUDES)
override CFLAGS += -fvisibility=hidden override CFLAGS += -fvisibility=hidden
override CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 override CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
# flags specific for shared library
SHLIB_FLAGS := -DSHARED
ifeq ($(VERBOSE),1) ifeq ($(VERBOSE),1)
Q = Q =
else else
@ -126,14 +133,17 @@ all:
export srctree OUTPUT CC LD CFLAGS V export srctree OUTPUT CC LD CFLAGS V
include $(srctree)/tools/build/Makefile.include include $(srctree)/tools/build/Makefile.include
BPF_IN := $(OUTPUT)libbpf-in.o SHARED_OBJDIR := $(OUTPUT)sharedobjs/
STATIC_OBJDIR := $(OUTPUT)staticobjs/
BPF_IN_SHARED := $(SHARED_OBJDIR)libbpf-in.o
BPF_IN_STATIC := $(STATIC_OBJDIR)libbpf-in.o
VERSION_SCRIPT := libbpf.map VERSION_SCRIPT := libbpf.map
LIB_TARGET := $(addprefix $(OUTPUT),$(LIB_TARGET)) LIB_TARGET := $(addprefix $(OUTPUT),$(LIB_TARGET))
LIB_FILE := $(addprefix $(OUTPUT),$(LIB_FILE)) LIB_FILE := $(addprefix $(OUTPUT),$(LIB_FILE))
PC_FILE := $(addprefix $(OUTPUT),$(PC_FILE)) PC_FILE := $(addprefix $(OUTPUT),$(PC_FILE))
GLOBAL_SYM_COUNT = $(shell readelf -s --wide $(BPF_IN) | \ GLOBAL_SYM_COUNT = $(shell readelf -s --wide $(BPF_IN_SHARED) | \
cut -d "@" -f1 | sed 's/_v[0-9]_[0-9]_[0-9].*//' | \ cut -d "@" -f1 | sed 's/_v[0-9]_[0-9]_[0-9].*//' | \
awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {print $$8}' | \ awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {print $$8}' | \
sort -u | wc -l) sort -u | wc -l)
@ -155,7 +165,7 @@ all: fixdep
all_cmd: $(CMD_TARGETS) check all_cmd: $(CMD_TARGETS) check
$(BPF_IN): force elfdep bpfdep $(BPF_IN_SHARED): force elfdep bpfdep
@(test -f ../../include/uapi/linux/bpf.h -a -f ../../../include/uapi/linux/bpf.h && ( \ @(test -f ../../include/uapi/linux/bpf.h -a -f ../../../include/uapi/linux/bpf.h && ( \
(diff -B ../../include/uapi/linux/bpf.h ../../../include/uapi/linux/bpf.h >/dev/null) || \ (diff -B ../../include/uapi/linux/bpf.h ../../../include/uapi/linux/bpf.h >/dev/null) || \
echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/bpf.h' differs from latest version at 'include/uapi/linux/bpf.h'" >&2 )) || true echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/bpf.h' differs from latest version at 'include/uapi/linux/bpf.h'" >&2 )) || true
@ -171,17 +181,20 @@ $(BPF_IN): force elfdep bpfdep
@(test -f ../../include/uapi/linux/if_xdp.h -a -f ../../../include/uapi/linux/if_xdp.h && ( \ @(test -f ../../include/uapi/linux/if_xdp.h -a -f ../../../include/uapi/linux/if_xdp.h && ( \
(diff -B ../../include/uapi/linux/if_xdp.h ../../../include/uapi/linux/if_xdp.h >/dev/null) || \ (diff -B ../../include/uapi/linux/if_xdp.h ../../../include/uapi/linux/if_xdp.h >/dev/null) || \
echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/if_xdp.h' differs from latest version at 'include/uapi/linux/if_xdp.h'" >&2 )) || true echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/if_xdp.h' differs from latest version at 'include/uapi/linux/if_xdp.h'" >&2 )) || true
$(Q)$(MAKE) $(build)=libbpf $(Q)$(MAKE) $(build)=libbpf OUTPUT=$(SHARED_OBJDIR) CFLAGS="$(CFLAGS) $(SHLIB_FLAGS)"
$(BPF_IN_STATIC): force elfdep bpfdep
$(Q)$(MAKE) $(build)=libbpf OUTPUT=$(STATIC_OBJDIR)
$(OUTPUT)libbpf.so: $(OUTPUT)libbpf.so.$(LIBBPF_VERSION) $(OUTPUT)libbpf.so: $(OUTPUT)libbpf.so.$(LIBBPF_VERSION)
$(OUTPUT)libbpf.so.$(LIBBPF_VERSION): $(BPF_IN) $(OUTPUT)libbpf.so.$(LIBBPF_VERSION): $(BPF_IN_SHARED)
$(QUIET_LINK)$(CC) --shared -Wl,-soname,libbpf.so.$(LIBBPF_MAJOR_VERSION) \ $(QUIET_LINK)$(CC) --shared -Wl,-soname,libbpf.so.$(LIBBPF_MAJOR_VERSION) \
-Wl,--version-script=$(VERSION_SCRIPT) $^ -lelf -o $@ -Wl,--version-script=$(VERSION_SCRIPT) $^ -lelf -o $@
@ln -sf $(@F) $(OUTPUT)libbpf.so @ln -sf $(@F) $(OUTPUT)libbpf.so
@ln -sf $(@F) $(OUTPUT)libbpf.so.$(LIBBPF_MAJOR_VERSION) @ln -sf $(@F) $(OUTPUT)libbpf.so.$(LIBBPF_MAJOR_VERSION)
$(OUTPUT)libbpf.a: $(BPF_IN) $(OUTPUT)libbpf.a: $(BPF_IN_STATIC)
$(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^ $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^
$(OUTPUT)test_libbpf: test_libbpf.cpp $(OUTPUT)libbpf.a $(OUTPUT)test_libbpf: test_libbpf.cpp $(OUTPUT)libbpf.a
@ -197,7 +210,7 @@ check: check_abi
check_abi: $(OUTPUT)libbpf.so check_abi: $(OUTPUT)libbpf.so
@if [ "$(GLOBAL_SYM_COUNT)" != "$(VERSIONED_SYM_COUNT)" ]; then \ @if [ "$(GLOBAL_SYM_COUNT)" != "$(VERSIONED_SYM_COUNT)" ]; then \
echo "Warning: Num of global symbols in $(BPF_IN)" \ echo "Warning: Num of global symbols in $(BPF_IN_SHARED)" \
"($(GLOBAL_SYM_COUNT)) does NOT match with num of" \ "($(GLOBAL_SYM_COUNT)) does NOT match with num of" \
"versioned symbols in $^ ($(VERSIONED_SYM_COUNT))." \ "versioned symbols in $^ ($(VERSIONED_SYM_COUNT))." \
"Please make sure all LIBBPF_API symbols are" \ "Please make sure all LIBBPF_API symbols are" \
@ -255,9 +268,9 @@ config-clean:
$(Q)$(MAKE) -C $(srctree)/tools/build/feature/ clean >/dev/null $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ clean >/dev/null
clean: clean:
$(call QUIET_CLEAN, libbpf) $(RM) $(TARGETS) $(CXX_TEST_TARGET) \ $(call QUIET_CLEAN, libbpf) $(RM) -rf $(TARGETS) $(CXX_TEST_TARGET) \
*.o *~ *.a *.so *.so.$(LIBBPF_MAJOR_VERSION) .*.d .*.cmd \ *.o *~ *.a *.so *.so.$(LIBBPF_MAJOR_VERSION) .*.d .*.cmd \
*.pc LIBBPF-CFLAGS *.pc LIBBPF-CFLAGS $(SHARED_OBJDIR) $(STATIC_OBJDIR)
$(call QUIET_CLEAN, core-gen) $(RM) $(OUTPUT)FEATURE-DUMP.libbpf $(call QUIET_CLEAN, core-gen) $(RM) $(OUTPUT)FEATURE-DUMP.libbpf

View File

@ -34,6 +34,22 @@
(offsetof(TYPE, FIELD) + sizeof(((TYPE *)0)->FIELD)) (offsetof(TYPE, FIELD) + sizeof(((TYPE *)0)->FIELD))
#endif #endif
/* Symbol versioning is different between static and shared library.
* Properly versioned symbols are needed for shared library, but
* only the symbol of the new version is needed for static library.
*/
#ifdef SHARED
# define COMPAT_VERSION(internal_name, api_name, version) \
asm(".symver " #internal_name "," #api_name "@" #version);
# define DEFAULT_VERSION(internal_name, api_name, version) \
asm(".symver " #internal_name "," #api_name "@@" #version);
#else
# define COMPAT_VERSION(internal_name, api_name, version)
# define DEFAULT_VERSION(internal_name, api_name, version) \
extern typeof(internal_name) api_name \
__attribute__((alias(#internal_name)));
#endif
extern void libbpf_print(enum libbpf_print_level level, extern void libbpf_print(enum libbpf_print_level level,
const char *format, ...) const char *format, ...)
__attribute__((format(printf, 2, 3))); __attribute__((format(printf, 2, 3)));

View File

@ -261,8 +261,8 @@ int xsk_umem__create_v0_0_2(struct xsk_umem **umem_ptr, void *umem_area,
return xsk_umem__create_v0_0_4(umem_ptr, umem_area, size, fill, comp, return xsk_umem__create_v0_0_4(umem_ptr, umem_area, size, fill, comp,
&config); &config);
} }
asm(".symver xsk_umem__create_v0_0_2, xsk_umem__create@LIBBPF_0.0.2"); COMPAT_VERSION(xsk_umem__create_v0_0_2, xsk_umem__create, LIBBPF_0.0.2)
asm(".symver xsk_umem__create_v0_0_4, xsk_umem__create@@LIBBPF_0.0.4"); DEFAULT_VERSION(xsk_umem__create_v0_0_4, xsk_umem__create, LIBBPF_0.0.4)
static int xsk_load_xdp_prog(struct xsk_socket *xsk) static int xsk_load_xdp_prog(struct xsk_socket *xsk)
{ {

View File

@ -195,7 +195,7 @@ static void run_test(int cgroup_fd)
if (CHECK_FAIL(pthread_create(&tid, NULL, server_thread, if (CHECK_FAIL(pthread_create(&tid, NULL, server_thread,
(void *)&server_fd))) (void *)&server_fd)))
goto close_bpf_object; goto close_server_fd;
pthread_mutex_lock(&server_started_mtx); pthread_mutex_lock(&server_started_mtx);
pthread_cond_wait(&server_started, &server_started_mtx); pthread_cond_wait(&server_started, &server_started_mtx);

View File

@ -260,13 +260,14 @@ void test_tcp_rtt(void)
if (CHECK_FAIL(pthread_create(&tid, NULL, server_thread, if (CHECK_FAIL(pthread_create(&tid, NULL, server_thread,
(void *)&server_fd))) (void *)&server_fd)))
goto close_cgroup_fd; goto close_server_fd;
pthread_mutex_lock(&server_started_mtx); pthread_mutex_lock(&server_started_mtx);
pthread_cond_wait(&server_started, &server_started_mtx); pthread_cond_wait(&server_started, &server_started_mtx);
pthread_mutex_unlock(&server_started_mtx); pthread_mutex_unlock(&server_started_mtx);
CHECK_FAIL(run_test(cgroup_fd, server_fd)); CHECK_FAIL(run_test(cgroup_fd, server_fd));
close_server_fd:
close(server_fd); close(server_fd);
close_cgroup_fd: close_cgroup_fd:
close(cgroup_fd); close(cgroup_fd);

View File

@ -63,6 +63,9 @@ fi
# Setup # Setup
tc qdisc add dev lo ingress tc qdisc add dev lo ingress
echo 0 > /proc/sys/net/ipv4/conf/default/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/lo/rp_filter
echo "Testing IPv4..." echo "Testing IPv4..."
# Drops all IP/UDP packets coming from port 9 # Drops all IP/UDP packets coming from port 9

View File

@ -314,15 +314,15 @@ test_gso()
command -v nc >/dev/null 2>&1 || \ command -v nc >/dev/null 2>&1 || \
{ echo >&2 "nc is not available: skipping TSO tests"; return; } { echo >&2 "nc is not available: skipping TSO tests"; return; }
# listen on IPv*_DST, capture TCP into $TMPFILE # listen on port 9000, capture TCP into $TMPFILE
if [ "${PROTO}" == "IPv4" ] ; then if [ "${PROTO}" == "IPv4" ] ; then
IP_DST=${IPv4_DST} IP_DST=${IPv4_DST}
ip netns exec ${NS3} bash -c \ ip netns exec ${NS3} bash -c \
"nc -4 -l -s ${IPv4_DST} -p 9000 > ${TMPFILE} &" "nc -4 -l -p 9000 > ${TMPFILE} &"
elif [ "${PROTO}" == "IPv6" ] ; then elif [ "${PROTO}" == "IPv6" ] ; then
IP_DST=${IPv6_DST} IP_DST=${IPv6_DST}
ip netns exec ${NS3} bash -c \ ip netns exec ${NS3} bash -c \
"nc -6 -l -s ${IPv6_DST} -p 9000 > ${TMPFILE} &" "nc -6 -l -p 9000 > ${TMPFILE} &"
RET=$? RET=$?
else else
echo " test_gso: unknown PROTO: ${PROTO}" echo " test_gso: unknown PROTO: ${PROTO}"