Message ID | 20200904142739.26353-2-mark.d.gray@redhat.com |
---|---|
State | Changes Requested |
Headers | show |
Series | [ovs-dev,v5,1/3] id-pool: Add interface to check if id has been allocated | expand |
Bleep bloop. Greetings Mark Gray, I am a robot and I have tried out your patch. Thanks for your contribution. I encountered some error that I wasn't expecting. See the details below. checkpatch: WARNING: Line is 80 characters long (recommended limit is 79) #228 FILE: lib/dpif-netlink.c:542: hmap_insert(&handler->channels, &channel->hmap_node, hash_int(port_idx, 0)); Lines checked: 629, Warnings: 1, Errors: 0 build: depbase=`echo lib/socket-util-unix.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\ /bin/sh ./libtool --tag=CC --mode=compile gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ./include -I ./include -I ./lib -I ./lib -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror -g -O2 -DHAVE_LD_AVX512_GOOD -MT lib/socket-util-unix.lo -MD -MP -MF $depbase.Tpo -c -o lib/socket-util-unix.lo lib/socket-util-unix.c &&\ mv -f $depbase.Tpo $depbase.Plo libtool: compile: gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ./include -I ./include -I ./lib -I ./lib -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror -g -O2 -DHAVE_LD_AVX512_GOOD -MT lib/socket-util-unix.lo -MD -MP -MF lib/.deps/socket-util-unix.Tpo -c lib/socket-util-unix.c -o lib/socket-util-unix.o depbase=`echo lib/stream-unix.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\ /bin/sh ./libtool --tag=CC --mode=compile gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ./include -I ./include -I ./lib -I ./lib -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror -g -O2 -DHAVE_LD_AVX512_GOOD -MT lib/stream-unix.lo -MD -MP -MF $depbase.Tpo -c -o lib/stream-unix.lo lib/stream-unix.c &&\ mv -f $depbase.Tpo $depbase.Plo libtool: compile: gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ./include -I ./include -I ./lib -I ./lib -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror -g -O2 -DHAVE_LD_AVX512_GOOD -MT lib/stream-unix.lo -MD -MP -MF lib/.deps/stream-unix.Tpo -c lib/stream-unix.c -o lib/stream-unix.o depbase=`echo lib/dpif-netlink.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\ /bin/sh ./libtool --tag=CC --mode=compile gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ./include -I ./include -I ./lib -I ./lib -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror -g -O2 -DHAVE_LD_AVX512_GOOD -MT lib/dpif-netlink.lo -MD -MP -MF $depbase.Tpo -c -o lib/dpif-netlink.lo lib/dpif-netlink.c &&\ mv -f $depbase.Tpo $depbase.Plo libtool: compile: gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ./include -I ./include -I ./lib -I ./lib -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror -g -O2 -DHAVE_LD_AVX512_GOOD -MT lib/dpif-netlink.lo -MD -MP -MF lib/.deps/dpif-netlink.Tpo -c lib/dpif-netlink.c -o lib/dpif-netlink.o lib/dpif-netlink.c: In function 'dpif_netlink_port_del': lib/dpif-netlink.c:1025:8: error: 'channel' may be used uninitialized in this function [-Werror=maybe-uninitialized] if (!channel) { ^ lib/dpif-netlink.c:992:26: note: 'channel' was declared here struct dpif_channel *channel; ^ cc1: all warnings being treated as errors make[2]: *** [lib/dpif-netlink.lo] Error 1 make[2]: Leaving directory `/var/lib/jenkins/jobs/0day_robot_upstream_build_from_pw/workspace' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `/var/lib/jenkins/jobs/0day_robot_upstream_build_from_pw/workspace' make: *** [all] Error 2 Please check this out. If you feel there has been an error, please email aconole@redhat.com Thanks, 0-day Robot
On 04/09/2020 16:03, 0-day Robot wrote: > Bleep bloop. Greetings Mark Gray, I am a robot and I have tried out your patch. > Thanks for your contribution. > > I encountered some error that I wasn't expecting. See the details below. Thanks 0-day > > > checkpatch: > WARNING: Line is 80 characters long (recommended limit is 79) > #228 FILE: lib/dpif-netlink.c:542: > hmap_insert(&handler->channels, &channel->hmap_node, hash_int(port_idx, 0)); > > Lines checked: 629, Warnings: 1, Errors: 0 Forgot to run checkpatch this time! > > > build: > depbase=`echo lib/socket-util-unix.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\ > /bin/sh ./libtool --tag=CC --mode=compile gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ./include -I ./include -I ./lib -I ./lib -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror -g -O2 -DHAVE_LD_AVX512_GOOD -MT lib/socket-util-unix.lo -MD -MP -MF $depbase.Tpo -c -o lib/socket-util-unix.lo lib/socket-util-unix.c &&\ > mv -f $depbase.Tpo $depbase.Plo > libtool: compile: gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ./include -I ./include -I ./lib -I ./lib -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror -g -O2 -DHAVE_LD_AVX512_GOOD -MT lib/socket-util-unix.lo -MD -MP -MF lib/.deps/socket-util-unix.Tpo -c lib/socket-util-unix.c -o lib/socket-util-unix.o > depbase=`echo lib/stream-unix.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\ > /bin/sh ./libtool --tag=CC --mode=compile gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ./include -I ./include -I ./lib -I ./lib -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror -g -O2 -DHAVE_LD_AVX512_GOOD -MT lib/stream-unix.lo -MD -MP -MF $depbase.Tpo -c -o lib/stream-unix.lo lib/stream-unix.c &&\ > mv -f $depbase.Tpo $depbase.Plo > libtool: compile: gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ./include -I ./include -I ./lib -I ./lib -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror -g -O2 -DHAVE_LD_AVX512_GOOD -MT lib/stream-unix.lo -MD -MP -MF lib/.deps/stream-unix.Tpo -c lib/stream-unix.c -o lib/stream-unix.o > depbase=`echo lib/dpif-netlink.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\ > /bin/sh ./libtool --tag=CC --mode=compile gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ./include -I ./include -I ./lib -I ./lib -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror -g -O2 -DHAVE_LD_AVX512_GOOD -MT lib/dpif-netlink.lo -MD -MP -MF $depbase.Tpo -c -o lib/dpif-netlink.lo lib/dpif-netlink.c &&\ > mv -f $depbase.Tpo $depbase.Plo > libtool: compile: gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ./include -I ./include -I ./lib -I ./lib -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror -g -O2 -DHAVE_LD_AVX512_GOOD -MT lib/dpif-netlink.lo -MD -MP -MF lib/.deps/dpif-netlink.Tpo -c lib/dpif-netlink.c -o lib/dpif-netlink.o > lib/dpif-netlink.c: In function 'dpif_netlink_port_del': > lib/dpif-netlink.c:1025:8: error: 'channel' may be used uninitialized in this function [-Werror=maybe-uninitialized] > if (!channel) { > ^ > lib/dpif-netlink.c:992:26: note: 'channel' was declared here > struct dpif_channel *channel; > ^ This is a potential error/warning. Interestingly, I am unable to reproduce this in my own environment and the travis/cirrus builds are also passing. -Wmaybe-uninitialized only displays messages in optimizing compilation (which is enabled across all 4 builds - 0-day, cirrus, travis, and min) and is enabled by -Wall or -Wextra (again, this is enabled across all). > cc1: all warnings being treated as errors > make[2]: *** [lib/dpif-netlink.lo] Error 1 > make[2]: Leaving directory `/var/lib/jenkins/jobs/0day_robot_upstream_build_from_pw/workspace' > make[1]: *** [all-recursive] Error 1 > make[1]: Leaving directory `/var/lib/jenkins/jobs/0day_robot_upstream_build_from_pw/workspace' > make: *** [all] Error 2 > > > Please check this out. If you feel there has been an error, please email aconole@redhat.com > > Thanks, > 0-day Robot >
Mark Gray <mark.d.gray@redhat.com> writes: > On 04/09/2020 16:03, 0-day Robot wrote: >> Bleep bloop. Greetings Mark Gray, I am a robot and I have tried out your patch. >> Thanks for your contribution. >> >> I encountered some error that I wasn't expecting. See the details below. > > Thanks 0-day > >> >> >> checkpatch: >> WARNING: Line is 80 characters long (recommended limit is 79) >> #228 FILE: lib/dpif-netlink.c:542: >> hmap_insert(&handler->channels, &channel->hmap_node, hash_int(port_idx, 0)); >> >> Lines checked: 629, Warnings: 1, Errors: 0 > > Forgot to run checkpatch this time! >> >> >> build: >> depbase=`echo lib/socket-util-unix.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\ >> /bin/sh ./libtool --tag=CC --mode=compile gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ./include -I ./include -I ./lib -I ./lib -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror -g -O2 -DHAVE_LD_AVX512_GOOD -MT lib/socket-util-unix.lo -MD -MP -MF $depbase.Tpo -c -o lib/socket-util-unix.lo lib/socket-util-unix.c &&\ >> mv -f $depbase.Tpo $depbase.Plo >> libtool: compile: gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ./include -I ./include -I ./lib -I ./lib -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror -g -O2 -DHAVE_LD_AVX512_GOOD -MT lib/socket-util-unix.lo -MD -MP -MF lib/.deps/socket-util-unix.Tpo -c lib/socket-util-unix.c -o lib/socket-util-unix.o >> depbase=`echo lib/stream-unix.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\ >> /bin/sh ./libtool --tag=CC --mode=compile gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ./include -I ./include -I ./lib -I ./lib -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror -g -O2 -DHAVE_LD_AVX512_GOOD -MT lib/stream-unix.lo -MD -MP -MF $depbase.Tpo -c -o lib/stream-unix.lo lib/stream-unix.c &&\ >> mv -f $depbase.Tpo $depbase.Plo >> libtool: compile: gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ./include -I ./include -I ./lib -I ./lib -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror -g -O2 -DHAVE_LD_AVX512_GOOD -MT lib/stream-unix.lo -MD -MP -MF lib/.deps/stream-unix.Tpo -c lib/stream-unix.c -o lib/stream-unix.o >> depbase=`echo lib/dpif-netlink.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\ >> /bin/sh ./libtool --tag=CC --mode=compile gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ./include -I ./include -I ./lib -I ./lib -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror -g -O2 -DHAVE_LD_AVX512_GOOD -MT lib/dpif-netlink.lo -MD -MP -MF $depbase.Tpo -c -o lib/dpif-netlink.lo lib/dpif-netlink.c &&\ >> mv -f $depbase.Tpo $depbase.Plo >> libtool: compile: gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ./include -I ./include -I ./lib -I ./lib -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror -g -O2 -DHAVE_LD_AVX512_GOOD -MT lib/dpif-netlink.lo -MD -MP -MF lib/.deps/dpif-netlink.Tpo -c lib/dpif-netlink.c -o lib/dpif-netlink.o >> lib/dpif-netlink.c: In function 'dpif_netlink_port_del': >> lib/dpif-netlink.c:1025:8: error: 'channel' may be used uninitialized in this function [-Werror=maybe-uninitialized] >> if (!channel) { >> ^ >> lib/dpif-netlink.c:992:26: note: 'channel' was declared here >> struct dpif_channel *channel; >> ^ > > This is a potential error/warning. Interestingly, I am unable to > reproduce this in my own environment and the travis/cirrus builds are > also passing. -Wmaybe-uninitialized only displays messages in optimizing > compilation (which is enabled across all 4 builds - 0-day, cirrus, > travis, and min) and is enabled by -Wall or -Wextra (again, this is > enabled across all). The 0-day bot uses gcc 4.8, IIRC. Whatever is shipped with RHEL7. >> cc1: all warnings being treated as errors >> make[2]: *** [lib/dpif-netlink.lo] Error 1 >> make[2]: Leaving directory `/var/lib/jenkins/jobs/0day_robot_upstream_build_from_pw/workspace' >> make[1]: *** [all-recursive] Error 1 >> make[1]: Leaving directory `/var/lib/jenkins/jobs/0day_robot_upstream_build_from_pw/workspace' >> make: *** [all] Error 2 >> >> >> Please check this out. If you feel there has been an error, please email aconole@redhat.com >> >> Thanks, >> 0-day Robot >>
diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c index 7da4fb54d..0e38f697c 100644 --- a/lib/dpif-netlink.c +++ b/lib/dpif-netlink.c @@ -37,6 +37,7 @@ #include "dpif-provider.h" #include "fat-rwlock.h" #include "flow.h" +#include "id-pool.h" #include "netdev-linux.h" #include "netdev-offload.h" #include "netdev-provider.h" @@ -160,6 +161,9 @@ static void dpif_netlink_flow_to_dpif_flow(struct dpif_flow *, /* One of the dpif channels between the kernel and userspace. */ struct dpif_channel { + struct hmap_node hmap_node; + struct dpif_handler *handler; + uint32_t port_idx; struct nl_sock *sock; /* Netlink socket. */ long long int last_poll; /* Last time this channel was polled. */ }; @@ -183,6 +187,8 @@ struct dpif_handler { int n_events; /* Num events returned by epoll_wait(). */ int event_offset; /* Offset into 'epoll_events'. */ + struct hmap channels; /* map of channels for each port. */ + #ifdef _WIN32 /* Pool of sockets. */ struct dpif_windows_vport_sock *vport_sock_pool; @@ -201,9 +207,8 @@ struct dpif_netlink { struct fat_rwlock upcall_lock; struct dpif_handler *handlers; uint32_t n_handlers; /* Num of upcall handlers. */ - struct dpif_channel *channels; /* Array of channels for each port. */ - int uc_array_size; /* Size of 'handler->channels' and */ - /* 'handler->epoll_events'. */ + + struct id_pool *port_ids; /* Set of added port ids */ /* Change notification. */ struct nl_sock *port_notifier; /* vport multicast group subscriber. */ @@ -287,6 +292,27 @@ close_nl_sock(struct nl_sock *sock) #endif } +static size_t +dpif_handler_channels_count(const struct dpif_handler *handler) +{ + return hmap_count(&handler->channels); +} + +static struct dpif_channel * +dpif_handler_channel_find(struct dpif_handler *handler, uint32_t idx) +{ + struct dpif_channel *channel; + + HMAP_FOR_EACH_WITH_HASH (channel, hmap_node, hash_int(idx, 0), + &handler->channels) { + if (channel->port_idx == idx) { + return channel; + } + } + + return NULL; +} + static struct dpif_netlink * dpif_netlink_cast(const struct dpif *dpif) { @@ -385,6 +411,8 @@ open_dpif(const struct dpif_netlink_dp *dp, struct dpif **dpifp) dpif->dp_ifindex = dp->dp_ifindex; dpif->user_features = dp->user_features; + dpif->port_ids = id_pool_create(0, MAX_PORTS); + *dpifp = &dpif->dpif; return 0; @@ -452,161 +480,139 @@ static bool vport_get_pid(struct dpif_netlink *dpif, uint32_t port_idx, uint32_t *upcall_pid) { - /* Since the nl_sock can only be assigned in either all - * or none "dpif" channels, the following check - * would suffice. */ - if (!dpif->channels[port_idx].sock) { + size_t i; + ovs_assert(!WINDOWS || dpif->n_handlers <= 1); + + if (!id_pool_has_id(dpif->port_ids, port_idx)) { return false; } - ovs_assert(!WINDOWS || dpif->n_handlers <= 1); - *upcall_pid = nl_sock_pid(dpif->channels[port_idx].sock); + /* The 'port_idx' should only be valid for a single handler. */ + for (i = 0; i < dpif->n_handlers; i++) { + struct dpif_channel *channel = + dpif_handler_channel_find(&dpif->handlers[i], port_idx); - return true; + if (channel) { + *upcall_pid = nl_sock_pid(channel->sock); + return true; + } + } + + return false; } static int vport_add_channel(struct dpif_netlink *dpif, odp_port_t port_no, struct nl_sock *sock) { - struct epoll_event event; uint32_t port_idx = odp_to_u32(port_no); + struct dpif_channel *channel; + struct dpif_handler *handler; + struct epoll_event event; size_t i; - int error; - if (dpif->handlers == NULL) { + if (dpif->handlers == NULL || + id_pool_has_id(dpif->port_ids, port_idx)) { close_nl_sock(sock); - return 0; + return EINVAL; } - /* We assume that the datapath densely chooses port numbers, which can - * therefore be used as an index into 'channels' and 'epoll_events' of - * 'dpif'. */ - if (port_idx >= dpif->uc_array_size) { - uint32_t new_size = port_idx + 1; - - if (new_size > MAX_PORTS) { - VLOG_WARN_RL(&error_rl, "%s: datapath port %"PRIu32" too big", - dpif_name(&dpif->dpif), port_no); - return EFBIG; - } + if (port_idx >= MAX_PORTS) { + VLOG_WARN_RL(&error_rl, "%s: datapath port %"PRIu32" too big", + dpif_name(&dpif->dpif), port_no); + return EFBIG; + } - dpif->channels = xrealloc(dpif->channels, - new_size * sizeof *dpif->channels); + handler = &dpif->handlers[0]; - for (i = dpif->uc_array_size; i < new_size; i++) { - dpif->channels[i].sock = NULL; + for (i = 0; i < dpif->n_handlers; i++) { + if (dpif_handler_channels_count(&dpif->handlers[i]) < + dpif_handler_channels_count(handler)) { + handler = &dpif->handlers[i]; } + } - for (i = 0; i < dpif->n_handlers; i++) { - struct dpif_handler *handler = &dpif->handlers[i]; - - handler->epoll_events = xrealloc(handler->epoll_events, - new_size * sizeof *handler->epoll_events); + channel = xmalloc(sizeof *channel); + channel->port_idx = port_idx; + channel->sock = sock; + channel->last_poll = LLONG_MIN; + channel->handler = handler; + hmap_insert(&handler->channels, &channel->hmap_node, hash_int(port_idx, 0)); - } - dpif->uc_array_size = new_size; - } + handler->epoll_events = xrealloc(handler->epoll_events, + dpif_handler_channels_count(handler) * + sizeof *handler->epoll_events); memset(&event, 0, sizeof event); event.events = EPOLLIN | EPOLLEXCLUSIVE; event.data.u32 = port_idx; - for (i = 0; i < dpif->n_handlers; i++) { - struct dpif_handler *handler = &dpif->handlers[i]; - -#ifndef _WIN32 - if (epoll_ctl(handler->epoll_fd, EPOLL_CTL_ADD, nl_sock_fd(sock), - &event) < 0) { - error = errno; - goto error; - } -#endif - } - dpif->channels[port_idx].sock = sock; - dpif->channels[port_idx].last_poll = LLONG_MIN; - - return 0; - -error: #ifndef _WIN32 - while (i--) { - epoll_ctl(dpif->handlers[i].epoll_fd, EPOLL_CTL_DEL, - nl_sock_fd(sock), NULL); + if (epoll_ctl(handler->epoll_fd, EPOLL_CTL_ADD, nl_sock_fd(sock), + &event) < 0) { + hmap_remove(&handler->channels, &channel->hmap_node); + free(channel); + id_pool_free_id(dpif->port_ids, port_idx); + return errno; } #endif - dpif->channels[port_idx].sock = NULL; - return error; + id_pool_add(dpif->port_ids, port_idx); + return 0; } static void -vport_del_channels(struct dpif_netlink *dpif, odp_port_t port_no) +vport_del_channel(struct dpif_netlink *dpif, + struct dpif_channel *channel) { - uint32_t port_idx = odp_to_u32(port_no); - size_t i; - - if (!dpif->handlers || port_idx >= dpif->uc_array_size - || !dpif->channels[port_idx].sock) { - return; - } - - for (i = 0; i < dpif->n_handlers; i++) { - struct dpif_handler *handler = &dpif->handlers[i]; + if (channel) { #ifndef _WIN32 - epoll_ctl(handler->epoll_fd, EPOLL_CTL_DEL, - nl_sock_fd(dpif->channels[port_idx].sock), NULL); + epoll_ctl(channel->handler->epoll_fd, EPOLL_CTL_DEL, + nl_sock_fd(channel->sock), NULL); + nl_sock_destroy(channel->sock); #endif - handler->event_offset = handler->n_events = 0; + hmap_remove(&channel->handler->channels, &channel->hmap_node); + id_pool_free_id(dpif->port_ids, channel->port_idx); + channel->handler->event_offset = channel->handler->n_events = 0; + free(channel); } -#ifndef _WIN32 - nl_sock_destroy(dpif->channels[port_idx].sock); -#endif - dpif->channels[port_idx].sock = NULL; } static void destroy_all_channels(struct dpif_netlink *dpif) OVS_REQ_WRLOCK(dpif->upcall_lock) { - unsigned int i; + size_t i; if (!dpif->handlers) { return; } - for (i = 0; i < dpif->uc_array_size; i++ ) { - struct dpif_netlink_vport vport_request; - uint32_t upcall_pids = 0; - - if (!dpif->channels[i].sock) { - continue; - } - - /* Turn off upcalls. */ - dpif_netlink_vport_init(&vport_request); - vport_request.cmd = OVS_VPORT_CMD_SET; - vport_request.dp_ifindex = dpif->dp_ifindex; - vport_request.port_no = u32_to_odp(i); - vport_request.n_upcall_pids = 1; - vport_request.upcall_pids = &upcall_pids; - dpif_netlink_vport_transact(&vport_request, NULL, NULL); - - vport_del_channels(dpif, u32_to_odp(i)); - } - for (i = 0; i < dpif->n_handlers; i++) { struct dpif_handler *handler = &dpif->handlers[i]; + struct dpif_channel *channel, *next; + + HMAP_FOR_EACH_SAFE (channel, next, hmap_node, &handler->channels) { + struct dpif_netlink_vport vport_request; + uint32_t upcall_pids = 0; + /* Turn off upcalls. */ + dpif_netlink_vport_init(&vport_request); + vport_request.cmd = OVS_VPORT_CMD_SET; + vport_request.dp_ifindex = dpif->dp_ifindex; + vport_request.port_no = u32_to_odp(channel->port_idx); + vport_request.n_upcall_pids = 1; + vport_request.upcall_pids = &upcall_pids; + dpif_netlink_vport_transact(&vport_request, NULL, NULL); + + vport_del_channel(dpif, channel); + } dpif_netlink_handler_uninit(handler); free(handler->epoll_events); } - free(dpif->channels); - free(dpif->handlers); + dpif->handlers = NULL; - dpif->channels = NULL; dpif->n_handlers = 0; - dpif->uc_array_size = 0; } static void @@ -618,9 +624,11 @@ dpif_netlink_close(struct dpif *dpif_) fat_rwlock_wrlock(&dpif->upcall_lock); destroy_all_channels(dpif); + id_pool_destroy(dpif->port_ids); fat_rwlock_unlock(&dpif->upcall_lock); fat_rwlock_destroy(&dpif->upcall_lock); + free(dpif); } @@ -981,8 +989,10 @@ dpif_netlink_port_del__(struct dpif_netlink *dpif, odp_port_t port_no) OVS_REQ_WRLOCK(dpif->upcall_lock) { struct dpif_netlink_vport vport; + struct dpif_channel *channel; struct dpif_port dpif_port; int error; + size_t i; error = dpif_netlink_port_query__(dpif, port_no, NULL, &dpif_port); if (error) { @@ -1003,7 +1013,18 @@ dpif_netlink_port_del__(struct dpif_netlink *dpif, odp_port_t port_no) #endif error = dpif_netlink_vport_transact(&vport, NULL, NULL); - vport_del_channels(dpif, port_no); + for (i = 0; i < dpif->n_handlers; i++) { + channel = dpif_handler_channel_find(&dpif->handlers[i], + odp_to_u32(port_no)); + if (channel) { + vport_del_channel(dpif, channel); + break; + } + } + + if (!channel) { + return EINVAL; + } if (!error && !ovs_tunnels_out_of_tree) { error = dpif_netlink_rtnl_port_destroy(dpif_port.name, dpif_port.type); @@ -1084,23 +1105,39 @@ dpif_netlink_port_get_pid__(const struct dpif_netlink *dpif, odp_port_t port_no) OVS_REQ_RDLOCK(dpif->upcall_lock) { + struct dpif_channel *min_channel = NULL, *found_channel = NULL; uint32_t port_idx = odp_to_u32(port_no); uint32_t pid = 0; + size_t i; + + /* The ODPP_NONE "reserved" port number uses the "ovs-system"'s + * channel, since it is not heavily loaded. */ + uint32_t idx = port_no == ODPP_NONE ? 0 : port_idx; - if (dpif->handlers && dpif->uc_array_size > 0) { - /* The ODPP_NONE "reserved" port number uses the "ovs-system"'s - * channel, since it is not heavily loaded. */ - uint32_t idx = port_idx >= dpif->uc_array_size ? 0 : port_idx; - - /* Needs to check in case the socket pointer is changed in between - * the holding of upcall_lock. A known case happens when the main - * thread deletes the vport while the handler thread is handling - * the upcall from that port. */ - if (dpif->channels[idx].sock) { - pid = nl_sock_pid(dpif->channels[idx].sock); + if (!id_pool_has_id(dpif->port_ids, port_idx)) { + return 0; + } + + if (dpif->handlers) { + for (i = 0; i < dpif->n_handlers; i++) { + if (dpif_handler_channel_find(&dpif->handlers[i], idx)) { + found_channel = dpif_handler_channel_find(&dpif->handlers[i], + idx); + break; + } + + if (dpif_handler_channel_find(&dpif->handlers[i], 0)) { + min_channel = dpif_handler_channel_find(&dpif->handlers[i], 0); + } } } + if (found_channel) { + pid = nl_sock_pid(found_channel->sock); + } else if (min_channel) { + pid = nl_sock_pid(min_channel->sock); + } + return pid; } @@ -2342,12 +2379,14 @@ dpif_netlink_operate(struct dpif *dpif_, struct dpif_op **ops, size_t n_ops, static void dpif_netlink_handler_uninit(struct dpif_handler *handler) { + hmap_destroy(&handler->channels); vport_delete_sock_pool(handler); } static int dpif_netlink_handler_init(struct dpif_handler *handler) { + hmap_init(&handler->channels); return vport_create_sock_pool(handler); } #else @@ -2355,6 +2394,7 @@ dpif_netlink_handler_init(struct dpif_handler *handler) static int dpif_netlink_handler_init(struct dpif_handler *handler) { + hmap_init(&handler->channels); handler->epoll_fd = epoll_create(10); return handler->epoll_fd < 0 ? errno : 0; } @@ -2362,6 +2402,7 @@ dpif_netlink_handler_init(struct dpif_handler *handler) static void dpif_netlink_handler_uninit(struct dpif_handler *handler) { + hmap_destroy(&handler->channels); close(handler->epoll_fd); } #endif @@ -2374,12 +2415,11 @@ static int dpif_netlink_refresh_channels(struct dpif_netlink *dpif, uint32_t n_handlers) OVS_REQ_WRLOCK(dpif->upcall_lock) { - unsigned long int *keep_channels; struct dpif_netlink_vport vport; - size_t keep_channels_nbits; struct nl_dump dump; uint64_t reply_stub[NL_DUMP_BUFSIZE / 8]; struct ofpbuf buf; + struct dpif_channel *channel; int retval = 0; size_t i; @@ -2412,13 +2452,9 @@ dpif_netlink_refresh_channels(struct dpif_netlink *dpif, uint32_t n_handlers) for (i = 0; i < n_handlers; i++) { struct dpif_handler *handler = &dpif->handlers[i]; - handler->event_offset = handler->n_events = 0; } - keep_channels_nbits = dpif->uc_array_size; - keep_channels = bitmap_allocate(keep_channels_nbits); - ofpbuf_use_stub(&buf, reply_stub, sizeof reply_stub); dpif_netlink_port_dump_start__(dpif, &dump); while (!dpif_netlink_port_dump_next__(dpif, &dump, &vport, &buf)) { @@ -2426,8 +2462,7 @@ dpif_netlink_refresh_channels(struct dpif_netlink *dpif, uint32_t n_handlers) uint32_t upcall_pid; int error; - if (port_no >= dpif->uc_array_size - || !vport_get_pid(dpif, port_no, &upcall_pid)) { + if (!vport_get_pid(dpif, port_no, &upcall_pid)) { struct nl_sock *sock; error = create_nl_sock(dpif, &sock); @@ -2475,25 +2510,17 @@ dpif_netlink_refresh_channels(struct dpif_netlink *dpif, uint32_t n_handlers) } } - if (port_no < keep_channels_nbits) { - bitmap_set1(keep_channels, port_no); - } continue; error: - vport_del_channels(dpif, vport.port_no); + for (i = 0; i < n_handlers; i++) { + channel = dpif_handler_channel_find(&dpif->handlers[i], port_no); + vport_del_channel(dpif, channel); + } } nl_dump_done(&dump); ofpbuf_uninit(&buf); - /* Discard any saved channels that we didn't reuse. */ - for (i = 0; i < keep_channels_nbits; i++) { - if (!bitmap_is_set(keep_channels, i)) { - vport_del_channels(dpif, u32_to_odp(i)); - } - } - free(keep_channels); - return retval; } @@ -2714,6 +2741,8 @@ dpif_netlink_recv__(struct dpif_netlink *dpif, uint32_t handler_id, OVS_REQ_RDLOCK(dpif->upcall_lock) { struct dpif_handler *handler; + size_t n_channels; + int read_tries = 0; if (!dpif->handlers || handler_id >= dpif->n_handlers) { @@ -2721,14 +2750,15 @@ dpif_netlink_recv__(struct dpif_netlink *dpif, uint32_t handler_id, } handler = &dpif->handlers[handler_id]; - if (handler->event_offset >= handler->n_events) { + n_channels = dpif_handler_channels_count(handler); + if (handler->event_offset >= handler->n_events && n_channels) { int retval; handler->event_offset = handler->n_events = 0; do { retval = epoll_wait(handler->epoll_fd, handler->epoll_events, - dpif->uc_array_size, 0); + n_channels, 0); } while (retval < 0 && errno == EINTR); if (retval < 0) { @@ -2741,7 +2771,10 @@ dpif_netlink_recv__(struct dpif_netlink *dpif, uint32_t handler_id, while (handler->event_offset < handler->n_events) { int idx = handler->epoll_events[handler->event_offset].data.u32; - struct dpif_channel *ch = &dpif->channels[idx]; + struct dpif_channel *ch = dpif_handler_channel_find(handler, idx); + if (!ch) { + return EAGAIN; + } handler->event_offset++; @@ -2845,12 +2878,14 @@ dpif_netlink_recv_purge__(struct dpif_netlink *dpif) if (dpif->handlers) { size_t i; - if (!dpif->channels[0].sock) { - return; - } - for (i = 0; i < dpif->uc_array_size; i++ ) { + for (i = 0; i < dpif->n_handlers; i++) { + struct dpif_handler *handler = &dpif->handlers[i]; + struct dpif_channel *channel; + + HMAP_FOR_EACH (channel, hmap_node, &handler->channels) { + nl_sock_drain(channel->sock); + } - nl_sock_drain(dpif->channels[i].sock); } } }