Remove the deleted stats from map
The xt_qtaguid module removes per uid stats when an app get uninstalled.
So eBPF map should not store the uninstalled stats either. This change
help fix the unknown iface problem as well.
Bug: 77987430
Test: android.app.usage.cts.NetworkUsageStatsTest
Change-Id: Ieb08833ecc35f76d27769042f197d889470faf7f
diff --git a/server/TrafficController.h b/server/TrafficController.h
index 2d58dd9..b810bf8 100644
--- a/server/TrafficController.h
+++ b/server/TrafficController.h
@@ -46,8 +46,6 @@
constexpr const int COUNTERSETS_LIMIT = 2;
-constexpr const int NONEXIST_COOKIE = 0;
-
namespace android {
namespace net {
@@ -127,6 +125,11 @@
private:
/*
* mCookieTagMap: Store the corresponding tag and uid for a specific socket.
+ * DO NOT hold any locks when modifying this map, otherwise when the untag
+ * operation is waiting for a lock hold by other process and there are more
+ * sockets being closed than can fit in the socket buffer of the netlink socket
+ * that receives them, then the kernel will drop some of these sockets and we
+ * won't delete their tags.
* Map Key: uint64_t socket cookie
* Map Value: struct UidTag, contains a uint32 uid and a uint32 tag.
*/
@@ -150,7 +153,7 @@
* Map Value: struct Stats, contains packet count and byte count of each
* transport protocol on egress and ingress direction.
*/
- base::unique_fd mUidStatsMap;
+ base::unique_fd mUidStatsMap GUARDED_BY(mDeleteStatsMutex);
/*
* mTagStatsMap: Store the traffic statistics for a specific combination of
@@ -161,7 +164,8 @@
* Map Value: struct Stats, contains packet count and byte count of each
* transport protocol on egress and ingress direction.
*/
- base::unique_fd mTagStatsMap;
+ base::unique_fd mTagStatsMap GUARDED_BY(mDeleteStatsMutex);
+
/*
* mIfaceIndexNameMap: Store the index name pair of each interface show up
@@ -200,6 +204,18 @@
std::mutex mOwnerMatchMutex;
+ // When aquiring both mOwnerMatchMutex and mDeleteStatsMutex,
+ // mOwnerMatchMutex must be grabbed first to prevent protential deadlock.
+ // This lock need to be hold when deleting from any stats map which we
+ // can iterate which are uidStatsMap and tagStatsMap. We don't need this
+ // lock to guard mUidCounterSetMap because we always directly look up /
+ // write / delete the map by uid. Also we don't need this lock for
+ // mCookieTagMap since the only time we need to iterate the map is
+ // deleteTagStats and we don't care if we failed and started from the
+ // beginning, since we will eventually scan through the map and delete all
+ // target entries.
+ std::mutex mDeleteStatsMutex;
+
netdutils::Status loadAndAttachProgram(bpf_attach_type type, const char* path, const char* name,
base::unique_fd& cg_fd);