summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/dpif-netdev.c1
-rw-r--r--lib/dpif-provider.h6
-rw-r--r--lib/dpif.c11
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)