diff --git a/drivers/net/ovpn/bind.c b/drivers/net/ovpn/bind.c
index e42b60cd04a9..a8e9a417e2bf 100644
--- a/drivers/net/ovpn/bind.c
+++ b/drivers/net/ovpn/bind.c
@@ -17,10 +17,18 @@
 /**
  * ovpn_bind_from_sockaddr - retrieve binding matching sockaddr
  * @ss: the sockaddr to match
+ * @gfp: GFP flags for the allocation. All callers reach this function with
+ *	 peer->lock (a spinlock) held, so the GFP must be atomic regardless of
+ *	 the outer context. Callers in process context (e.g. netlink handlers)
+ *	 should additionally OR in __GFP_ACCOUNT so the charge lands on the
+ *	 caller's memcg; callers on the RX float path (softirq, where current
+ *	 is unrelated to the userns owner) must pass plain GFP_ATOMIC to avoid
+ *	 mis-accounting to a random cgroup.
  *
  * Return: the bind matching the passed sockaddr if found, NULL otherwise
  */
-struct ovpn_bind *ovpn_bind_from_sockaddr(const struct sockaddr_storage *ss)
+struct ovpn_bind *ovpn_bind_from_sockaddr(const struct sockaddr_storage *ss,
+					  gfp_t gfp)
 {
 	struct ovpn_bind *bind;
 	size_t sa_len;
@@ -32,7 +40,7 @@ struct ovpn_bind *ovpn_bind_from_sockaddr(const struct sockaddr_storage *ss)
 	else
 		return ERR_PTR(-EAFNOSUPPORT);
 
-	bind = kzalloc_obj(*bind, GFP_ATOMIC);
+	bind = kzalloc_obj(*bind, gfp);
 	if (unlikely(!bind))
 		return ERR_PTR(-ENOMEM);
 
diff --git a/drivers/net/ovpn/bind.h b/drivers/net/ovpn/bind.h
index 4e0b8398bfd9..cda8c4888a35 100644
--- a/drivers/net/ovpn/bind.h
+++ b/drivers/net/ovpn/bind.h
@@ -95,7 +95,8 @@ static inline bool ovpn_bind_skb_src_match(const struct ovpn_bind *bind,
 	return true;
 }
 
-struct ovpn_bind *ovpn_bind_from_sockaddr(const struct sockaddr_storage *sa);
+struct ovpn_bind *ovpn_bind_from_sockaddr(const struct sockaddr_storage *sa,
+					  gfp_t gfp);
 void ovpn_bind_reset(struct ovpn_peer *peer, struct ovpn_bind *bind);
 
 #endif /* _NET_OVPN_OVPNBIND_H_ */
diff --git a/drivers/net/ovpn/crypto_aead.c b/drivers/net/ovpn/crypto_aead.c
index 8f07c418622b..0a3c93d198fe 100644
--- a/drivers/net/ovpn/crypto_aead.c
+++ b/drivers/net/ovpn/crypto_aead.c
@@ -414,7 +414,7 @@ ovpn_aead_crypto_key_slot_new(const struct ovpn_key_config *kc)
 		return ERR_PTR(-EINVAL);
 
 	/* build the key slot */
-	ks = kmalloc_obj(*ks);
+	ks = kmalloc_obj(*ks, GFP_KERNEL_ACCOUNT);
 	if (!ks)
 		return ERR_PTR(-ENOMEM);
 
diff --git a/drivers/net/ovpn/main.c b/drivers/net/ovpn/main.c
index 9993c1dfe471..425f4367f0ab 100644
--- a/drivers/net/ovpn/main.c
+++ b/drivers/net/ovpn/main.c
@@ -57,7 +57,7 @@ static int ovpn_mp_alloc(struct ovpn_priv *ovpn)
 	/* the peer container is fairly large, therefore we allocate it only in
 	 * MP mode
 	 */
-	ovpn->peers = kzalloc_obj(*ovpn->peers);
+	ovpn->peers = kzalloc_obj(*ovpn->peers, GFP_KERNEL_ACCOUNT);
 	if (!ovpn->peers)
 		return -ENOMEM;
 
diff --git a/drivers/net/ovpn/netlink.c b/drivers/net/ovpn/netlink.c
index 4c66c1ec497e..893dccdfaf64 100644
--- a/drivers/net/ovpn/netlink.c
+++ b/drivers/net/ovpn/netlink.c
@@ -295,7 +295,8 @@ static int ovpn_nl_peer_modify(struct ovpn_peer *peer, struct genl_info *info,
 		local_ip = ovpn_nl_attr_local_ip(attrs);
 
 		/* set peer sockaddr */
-		ret = ovpn_peer_reset_sockaddr(peer, &ss, local_ip);
+		ret = ovpn_peer_reset_sockaddr(peer, &ss, local_ip,
+					       GFP_ATOMIC | __GFP_ACCOUNT);
 		if (ret < 0) {
 			NL_SET_ERR_MSG_FMT_MOD(info->extack,
 					       "cannot set peer sockaddr: %d",
diff --git a/drivers/net/ovpn/peer.c b/drivers/net/ovpn/peer.c
index a09d61296425..511a7ce9b32b 100644
--- a/drivers/net/ovpn/peer.c
+++ b/drivers/net/ovpn/peer.c
@@ -95,7 +95,7 @@ struct ovpn_peer *ovpn_peer_new(struct ovpn_priv *ovpn, u32 id)
 	int ret;
 
 	/* alloc and init peer object */
-	peer = kzalloc_obj(*peer);
+	peer = kzalloc_obj(*peer, GFP_KERNEL_ACCOUNT);
 	if (!peer)
 		return ERR_PTR(-ENOMEM);
 
@@ -117,7 +117,7 @@ struct ovpn_peer *ovpn_peer_new(struct ovpn_priv *ovpn, u32 id)
 	ovpn_peer_stats_init(&peer->link_stats);
 	INIT_WORK(&peer->keepalive_work, ovpn_peer_keepalive_send);
 
-	ret = dst_cache_init(&peer->dst_cache, GFP_KERNEL);
+	ret = dst_cache_init(&peer->dst_cache, GFP_KERNEL_ACCOUNT);
 	if (ret < 0) {
 		netdev_err(ovpn->dev,
 			   "cannot initialize dst cache for peer %u\n",
@@ -126,7 +126,7 @@ struct ovpn_peer *ovpn_peer_new(struct ovpn_priv *ovpn, u32 id)
 		return ERR_PTR(ret);
 	}
 
-	netdev_hold(ovpn->dev, &peer->dev_tracker, GFP_KERNEL);
+	netdev_hold(ovpn->dev, &peer->dev_tracker, GFP_KERNEL_ACCOUNT);
 
 	return peer;
 }
@@ -136,12 +136,14 @@ struct ovpn_peer *ovpn_peer_new(struct ovpn_priv *ovpn, u32 id)
  * @peer: peer to recreate the binding for
  * @ss: sockaddr to use as remote endpoint for the binding
  * @local_ip: local IP for the binding
+ * @gfp: GFP flags for the bind allocation. See ovpn_bind_from_sockaddr() for
+ *	 the accounting trade-off between process-context and softirq callers.
  *
  * Return: 0 on success or a negative error code otherwise
  */
 int ovpn_peer_reset_sockaddr(struct ovpn_peer *peer,
 			     const struct sockaddr_storage *ss,
-			     const void *local_ip)
+			     const void *local_ip, gfp_t gfp)
 {
 	struct ovpn_bind *bind;
 	size_t ip_len;
@@ -149,7 +151,7 @@ int ovpn_peer_reset_sockaddr(struct ovpn_peer *peer,
 	lockdep_assert_held(&peer->lock);
 
 	/* create new ovpn_bind object */
-	bind = ovpn_bind_from_sockaddr(ss);
+	bind = ovpn_bind_from_sockaddr(ss, gfp);
 	if (IS_ERR(bind))
 		return PTR_ERR(bind);
 
@@ -281,9 +283,13 @@ void ovpn_peer_endpoints_update(struct ovpn_peer *peer, struct sk_buff *skb)
 	if (likely(!salen))
 		goto unlock;
 
+	/* RX float path runs in softirq context: __GFP_ACCOUNT would charge
+	 * whatever cgroup is on-CPU when the packet arrives, not the userns
+	 * owner, so pass plain GFP_ATOMIC and skip accounting on this path.
+	 */
 	if (unlikely(ovpn_peer_reset_sockaddr(peer,
 					      (struct sockaddr_storage *)&ss,
-					      local_ip) < 0))
+					      local_ip, GFP_ATOMIC) < 0))
 		goto unlock;
 
 	net_dbg_ratelimited("%s: peer %d floated to %pIScp",
diff --git a/drivers/net/ovpn/peer.h b/drivers/net/ovpn/peer.h
index 86c8cffada6d..1bfc66821739 100644
--- a/drivers/net/ovpn/peer.h
+++ b/drivers/net/ovpn/peer.h
@@ -159,6 +159,6 @@ void ovpn_peer_keepalive_work(struct work_struct *work);
 void ovpn_peer_endpoints_update(struct ovpn_peer *peer, struct sk_buff *skb);
 int ovpn_peer_reset_sockaddr(struct ovpn_peer *peer,
 			     const struct sockaddr_storage *ss,
-			     const void *local_ip);
+			     const void *local_ip, gfp_t gfp);
 
 #endif /* _NET_OVPN_OVPNPEER_H_ */
diff --git a/drivers/net/ovpn/socket.c b/drivers/net/ovpn/socket.c
index 517caa64a4fe..45d6a497bffb 100644
--- a/drivers/net/ovpn/socket.c
+++ b/drivers/net/ovpn/socket.c
@@ -191,7 +191,7 @@ struct ovpn_socket *ovpn_socket_new(struct socket *sock, struct ovpn_peer *peer)
 
 	/* socket is not owned: attach to this ovpn instance */
 
-	ovpn_sock = kzalloc_obj(*ovpn_sock);
+	ovpn_sock = kzalloc_obj(*ovpn_sock, GFP_KERNEL_ACCOUNT);
 	if (!ovpn_sock) {
 		ovpn_sock = ERR_PTR(-ENOMEM);
 		goto sock_release;
@@ -213,7 +213,7 @@ struct ovpn_socket *ovpn_socket_new(struct socket *sock, struct ovpn_peer *peer)
 		 */
 		ovpn_sock->ovpn = peer->ovpn;
 		netdev_hold(peer->ovpn->dev, &ovpn_sock->dev_tracker,
-			    GFP_KERNEL);
+			    GFP_KERNEL_ACCOUNT);
 	}
 
 	/* the newly created ovpn_socket is holding reference to sk,
