This patch makes all of the users of 'struct nl_dump' allocate their own buffers to pass down to nl_dump_next(). This paves the way for allowing multithreaded flow dumping.
Signed-off-by: Joe Stringer <joestrin...@nicira.com> --- lib/dpif-linux.c | 16 ++++++++++++---- lib/netdev-linux.c | 42 ++++++++++++++++++++++++++++-------------- lib/netlink-socket.c | 1 - lib/netlink-socket.h | 1 - lib/route-table.c | 12 ++++++++---- 5 files changed, 48 insertions(+), 24 deletions(-) diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c index d985f4b..45a2492 100644 --- a/lib/dpif-linux.c +++ b/lib/dpif-linux.c @@ -192,7 +192,7 @@ static int dpif_linux_enumerate(struct sset *all_dps) { struct nl_dump dump; - struct ofpbuf msg; + struct ofpbuf msg, buf; int error; error = dpif_linux_init(); @@ -200,14 +200,16 @@ dpif_linux_enumerate(struct sset *all_dps) return error; } + ofpbuf_init(&buf, 4096); dpif_linux_dp_dump_start(&dump); - while (nl_dump_next(&dump, &msg, &dump.buffer)) { + while (nl_dump_next(&dump, &msg, &buf)) { struct dpif_linux_dp dp; if (!dpif_linux_dp_from_ofpbuf(&dp, &msg)) { sset_add(all_dps, dp.name); } } + ofpbuf_uninit(&buf); return nl_dump_done(&dump); } @@ -707,6 +709,7 @@ dpif_linux_flow_flush(struct dpif *dpif_) struct dpif_linux_port_state { struct nl_dump dump; + struct ofpbuf buf; }; static void @@ -734,6 +737,7 @@ dpif_linux_port_dump_start(const struct dpif *dpif, void **statep) *statep = state = xmalloc(sizeof *state); dpif_linux_port_dump_start__(dpif, &state->dump); + ofpbuf_init(&state->buf, 4096); return 0; } @@ -767,7 +771,7 @@ dpif_linux_port_dump_next(const struct dpif *dpif OVS_UNUSED, void *state_, int error; error = dpif_linux_port_dump_next__(dpif, &state->dump, &vport, - &state->dump.buffer); + &state->buf); if (error) { return error; } @@ -783,6 +787,7 @@ dpif_linux_port_dump_done(const struct dpif *dpif_ OVS_UNUSED, void *state_) struct dpif_linux_port_state *state = state_; int error = nl_dump_done(&state->dump); + ofpbuf_uninit(&state->buf); free(state); return error; } @@ -1292,6 +1297,7 @@ dpif_linux_refresh_channels(struct dpif *dpif_) struct dpif_linux_vport vport; size_t keep_channels_nbits; struct nl_dump dump; + struct ofpbuf buf; int retval = 0; size_t i; @@ -1308,8 +1314,9 @@ dpif_linux_refresh_channels(struct dpif *dpif_) dpif->n_events = dpif->event_offset = 0; + ofpbuf_init(&buf, 4096); dpif_linux_port_dump_start__(dpif_, &dump); - while (!dpif_linux_port_dump_next__(dpif_, &dump, &vport, &dump.buffer)) { + while (!dpif_linux_port_dump_next__(dpif_, &dump, &vport, &buf)) { uint32_t port_no = odp_to_u32(vport.port_no); struct nl_sock *sock = (port_no < dpif->uc_array_size ? dpif->channels[port_no].sock @@ -1375,6 +1382,7 @@ dpif_linux_refresh_channels(struct dpif *dpif_) nl_sock_destroy(sock); } nl_dump_done(&dump); + ofpbuf_uninit(&buf); /* Discard any saved channels that we didn't reuse. */ for (i = 0; i < keep_channels_nbits; i++) { diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index 3a67612..84e776b 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -2053,8 +2053,13 @@ netdev_linux_get_queue_stats(const struct netdev *netdev_, return error; } +struct queue_dump_state { + struct nl_dump dump; + struct ofpbuf buf; +}; + static bool -start_queue_dump(const struct netdev *netdev, struct nl_dump *dump) +start_queue_dump(const struct netdev *netdev, struct queue_dump_state *state) { struct ofpbuf request; struct tcmsg *tcmsg; @@ -2064,11 +2069,20 @@ start_queue_dump(const struct netdev *netdev, struct nl_dump *dump) return false; } tcmsg->tcm_parent = 0; - nl_dump_start(dump, NETLINK_ROUTE, &request); + nl_dump_start(&state->dump, NETLINK_ROUTE, &request); ofpbuf_uninit(&request); + + ofpbuf_init(&state->buf, 4096); return true; } +static int +finish_queue_dump(struct queue_dump_state *state) +{ + ofpbuf_uninit(&state->buf); + return nl_dump_done(&state->dump); +} + struct netdev_linux_queue_state { unsigned int *queues; size_t cur_queue; @@ -2152,17 +2166,17 @@ netdev_linux_dump_queue_stats(const struct netdev *netdev_, ovs_mutex_lock(&netdev->mutex); error = tc_query_qdisc(netdev_); if (!error) { - struct nl_dump dump; + struct queue_dump_state state; if (!netdev->tc->ops->class_dump_stats) { error = EOPNOTSUPP; - } else if (!start_queue_dump(netdev_, &dump)) { + } else if (!start_queue_dump(netdev_, &state)) { error = ENODEV; } else { struct ofpbuf msg; int retval; - while (nl_dump_next(&dump, &msg, &dump.buffer)) { + while (nl_dump_next(&state.dump, &msg, &state.buf)) { retval = netdev->tc->ops->class_dump_stats(netdev_, &msg, cb, aux); if (retval) { @@ -2170,7 +2184,7 @@ netdev_linux_dump_queue_stats(const struct netdev *netdev_, } } - retval = nl_dump_done(&dump); + retval = finish_queue_dump(&state); if (retval) { error = retval; } @@ -2948,7 +2962,7 @@ static int htb_tc_load(struct netdev *netdev, struct ofpbuf *nlmsg OVS_UNUSED) { struct ofpbuf msg; - struct nl_dump dump; + struct queue_dump_state state; struct htb_class hc; /* Get qdisc options. */ @@ -2957,17 +2971,17 @@ htb_tc_load(struct netdev *netdev, struct ofpbuf *nlmsg OVS_UNUSED) htb_install__(netdev, hc.max_rate); /* Get queues. */ - if (!start_queue_dump(netdev, &dump)) { + if (!start_queue_dump(netdev, &state)) { return ENODEV; } - while (nl_dump_next(&dump, &msg, &dump.buffer)) { + while (nl_dump_next(&state.dump, &msg, &state.buf)) { unsigned int queue_id; if (!htb_parse_tcmsg__(&msg, &queue_id, &hc, NULL)) { htb_update_queue__(netdev, queue_id, &hc); } } - nl_dump_done(&dump); + finish_queue_dump(&state); return 0; } @@ -3448,18 +3462,18 @@ static int hfsc_tc_load(struct netdev *netdev, struct ofpbuf *nlmsg OVS_UNUSED) { struct ofpbuf msg; - struct nl_dump dump; + struct queue_dump_state state; struct hfsc_class hc; hc.max_rate = 0; hfsc_query_class__(netdev, tc_make_handle(1, 0xfffe), 0, &hc, NULL); hfsc_install__(netdev, hc.max_rate); - if (!start_queue_dump(netdev, &dump)) { + if (!start_queue_dump(netdev, &state)) { return ENODEV; } - while (nl_dump_next(&dump, &msg, &dump.buffer)) { + while (nl_dump_next(&state.dump, &msg, &state.buf)) { unsigned int queue_id; if (!hfsc_parse_tcmsg__(&msg, &queue_id, &hc, NULL)) { @@ -3467,7 +3481,7 @@ hfsc_tc_load(struct netdev *netdev, struct ofpbuf *nlmsg OVS_UNUSED) } } - nl_dump_done(&dump); + finish_queue_dump(&state); return 0; } diff --git a/lib/netlink-socket.c b/lib/netlink-socket.c index fce360d..d2b0973 100644 --- a/lib/netlink-socket.c +++ b/lib/netlink-socket.c @@ -689,7 +689,6 @@ nl_sock_drain(struct nl_sock *sock) void nl_dump_start(struct nl_dump *dump, int protocol, const struct ofpbuf *request) { - ofpbuf_init(&dump->buffer, 4096); dump->status = nl_pool_alloc(protocol, &dump->sock); if (dump->status) { return; diff --git a/lib/netlink-socket.h b/lib/netlink-socket.h index 038e632..4e1e588 100644 --- a/lib/netlink-socket.h +++ b/lib/netlink-socket.h @@ -99,7 +99,6 @@ void nl_transact_multiple(int protocol, struct nl_transaction **, size_t n); struct nl_dump { struct nl_sock *sock; /* Socket being dumped. */ uint32_t seq; /* Expected nlmsg_seq for replies. */ - struct ofpbuf buffer; /* Receive buffer currently being iterated. */ int status; /* 0=OK, EOF=done, or positive errno value. */ }; diff --git a/lib/route-table.c b/lib/route-table.c index 1a2be0d..1fab3b6 100644 --- a/lib/route-table.c +++ b/lib/route-table.c @@ -223,7 +223,7 @@ route_table_reset(void) { struct nl_dump dump; struct rtgenmsg *rtmsg; - struct ofpbuf request, reply; + struct ofpbuf request, reply, buf; route_map_clear(); route_table_valid = true; @@ -238,13 +238,15 @@ route_table_reset(void) nl_dump_start(&dump, NETLINK_ROUTE, &request); ofpbuf_uninit(&request); - while (nl_dump_next(&dump, &reply, &dump.buffer)) { + ofpbuf_init(&buf, 4096); + while (nl_dump_next(&dump, &reply, &buf)) { struct route_table_msg msg; if (route_table_parse(&reply, &msg)) { route_table_handle_msg(&msg); } } + ofpbuf_uninit(&buf); return nl_dump_done(&dump); } @@ -407,7 +409,7 @@ name_table_reset(void) { struct nl_dump dump; struct rtgenmsg *rtmsg; - struct ofpbuf request, reply; + struct ofpbuf request, reply, buf; name_table_valid = true; name_map_clear(); @@ -420,7 +422,8 @@ name_table_reset(void) nl_dump_start(&dump, NETLINK_ROUTE, &request); ofpbuf_uninit(&request); - while (nl_dump_next(&dump, &reply, &dump.buffer)) { + ofpbuf_init(&buf, 4096); + while (nl_dump_next(&dump, &reply, &buf)) { struct rtnetlink_link_change change; if (rtnetlink_link_parse(&reply, &change) @@ -434,6 +437,7 @@ name_table_reset(void) hmap_insert(&name_map, &nn->node, hash_int(nn->ifi_index, 0)); } } + ofpbuf_uninit(&buf); return nl_dump_done(&dump); } -- 1.7.9.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev