Both points are right, and v2 changes the description.
The Medium one is a wording defect. "A failed request" reads as covering
every request that fails, and the paths you list do still leave the key
away from the features: the NEW unwind after new_vport() fails, and
ovs_dp_reset_user_features() on the -EEXIST branch. They predate this
change and stay out of it, as the changelog says, but the closing
sentence promised more than ovs_dp_change() can deliver. v2 says "A
failed OVS_DP_CMD_SET then leaves both the features and the key alone",
and adds that a failed OVS_DP_CMD_NEW and the reset that follows it still
leave the key one enable ahead.
For the Low one, v2 names the reachability and the effect. The request
needs only CAP_NET_ADMIN, which a user namespace that owns a network
namespace carries. datapath_policy has no entry for
OVS_DP_ATTR_PER_CPU_PIDS and the operation skips strict validation, so an
empty attribute reaches the check that fails. A disable on a count of
zero reaches the WARN_ON_ONCE in static_key_dec_not_one(), which panics a
host that runs with panic_on_warn.
pw-bot: cr