diff options
-rw-r--r-- | lib/dpif-netdev.c | 1 | ||||
-rw-r--r-- | lib/dpif-provider.h | 6 | ||||
-rw-r--r-- | lib/dpif.c | 11 |
3 files changed, 12 insertions, 6 deletions
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 21a4f56d5..9270873c5 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -1466,7 +1466,6 @@ dpif_netdev_flow_dump_thread_destroy(struct dpif_flow_dump_thread *thread_) free(thread); } -/* XXX the caller must use 'actions' without quiescing */ static int dpif_netdev_flow_dump_next(struct dpif_flow_dump_thread *thread_, struct dpif_flow *flows, int max_flows) diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h index 2a765de4d..6a06cf8dd 100644 --- a/lib/dpif-provider.h +++ b/lib/dpif-provider.h @@ -253,11 +253,13 @@ struct dpif_class { * * If 'maskp' is nonnull, then on success '*maskp' will point to the * Netlink attributes for the flow's mask. '*mask_len' will be set to the - * length of the mask attributes. + * length of the mask attributes. Implementations may opt to point 'maskp' + * at RCU-protected data rather than making a copy in '*bufp'. * * If 'actionsp' is nonnull, then on success '*actionsp' will point to the * Netlink attributes for the flow's actions. '*actions_len' will be set to - * the length of the actions attributes. + * the length of the actions attributes. Implementations may opt to point + * 'actionsp' at RCU-protected data rather than making a copy in '*bufp'. * * If 'stats' is nonnull, then on success it must be updated with the * flow's statistics. */ diff --git a/lib/dpif.c b/lib/dpif.c index 5b9da4d71..a3258057c 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -842,7 +842,11 @@ dpif_flow_flush(struct dpif *dpif) * On success, 'flow' will be populated with the mask, actions and stats for * the datapath flow corresponding to 'key'. The mask and actions will point * within '*bufp'. - */ + * + * Implementations may opt to point 'flow->mask' and/or 'flow->actions' at + * RCU-protected data rather than making a copy of them. Therefore, callers + * that wish to hold these over quiescent periods must make a copy of these + * fields before quiescing. */ int dpif_flow_get(const struct dpif *dpif, const struct nlattr *key, size_t key_len, @@ -1030,8 +1034,9 @@ dpif_flow_dump_thread_destroy(struct dpif_flow_dump_thread *thread) * * All of the data stored into 'flows' is owned by the datapath, not by the * caller, and the caller must not modify or free it. The datapath guarantees - * that it remains accessible and unchanged until at least the next call to - * dpif_flow_dump_next() for 'thread'. */ + * that it remains accessible and unchanged until the first of: + * - The next call to dpif_flow_dump_next() for 'thread', or + * - The next rcu quiescent period. */ int dpif_flow_dump_next(struct dpif_flow_dump_thread *thread, struct dpif_flow *flows, int max_flows) |