loopback patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/impl/net/loopback/cogent/Makefile b/impl/net/loopback/cogent/Makefile | |
index a1921805..9298ee2c 100644 | |
--- a/impl/net/loopback/cogent/Makefile | |
+++ b/impl/net/loopback/cogent/Makefile | |
@@ -37,6 +37,7 @@ AHFILES= | |
LINUX_ACFILES= $(addprefix $(STDGUM)/gum/anti/, \ | |
common.ac) \ | |
plat/linux/linux_api.ac \ | |
+ plat/linux/alloc.ac \ | |
plat/linux/wrapper.ac \ | |
$(NULL) | |
diff --git a/impl/net/loopback/cogent/data/defns.txt b/impl/net/loopback/cogent/data/defns.txt | |
index 14cc02ce..129f9646 100644 | |
--- a/impl/net/loopback/cogent/data/defns.txt | |
+++ b/impl/net/loopback/cogent/data/defns.txt | |
@@ -9,4 +9,8 @@ cg_loopback_dev_free_cg | |
cg_always_on_cg | |
get_ts_info_timestamp_flags_cg | |
set_fields_in_pcpu_lstats | |
+cg_loopback_get_stats64_cg | |
+cg_loopback_xmit_cg | |
+update_loopback_stats | |
+newPCPULStats | |
diff --git a/impl/net/loopback/cogent/data/types.txt b/impl/net/loopback/cogent/data/types.txt | |
index f8c92d0f..c33fa708 100644 | |
--- a/impl/net/loopback/cogent/data/types.txt | |
+++ b/impl/net/loopback/cogent/data/types.txt | |
@@ -27,3 +27,4 @@ netdev_tx_t | |
cpu_possible_mask | |
nr_cpu_ids | |
netdev_alloc_pcpu_stats | |
+ | |
diff --git a/impl/net/loopback/cogent/plat/linux/abstract.h b/impl/net/loopback/cogent/plat/linux/abstract.h | |
index 1f76f674..ac99e250 100644 | |
--- a/impl/net/loopback/cogent/plat/linux/abstract.h | |
+++ b/impl/net/loopback/cogent/plat/linux/abstract.h | |
@@ -25,6 +25,8 @@ typedef struct _State SysState; | |
typedef struct u64_stats_sync U64StatsSyncAbstractType; | |
typedef struct net NetAbstractType; | |
typedef struct net_device NetDeviceAbstractType; | |
+typedef struct sk_buff SKBuffAbstractType; | |
+typedef struct pcpu_lstats PCPULStatsAbstractType; | |
#define likely(x) __builtin_expect(!!(x), 1) | |
#define unlikely(x) __builtin_expect(!!(x), 0) | |
diff --git a/impl/net/loopback/cogent/plat/linux/linux_api.ac b/impl/net/loopback/cogent/plat/linux/linux_api.ac | |
index 0b2750ed..2e12fdcf 100644 | |
--- a/impl/net/loopback/cogent/plat/linux/linux_api.ac | |
+++ b/impl/net/loopback/cogent/plat/linux/linux_api.ac | |
@@ -79,14 +79,20 @@ inline $ty:(SysState) free_netdev_ac($ty:((SysState, NetDeviceAbstractType)) arg | |
return args.p1; | |
} | |
+struct pcpu_lstats { | |
+ u64 packets; | |
+ u64 bytes; | |
+ struct u64_stats_sync syncp; | |
+}; | |
+ | |
inline $ty:(RR (SysState, NetDeviceAbstractType) () ()) netdev_alloc_pcpu_stats_ac($ty:((SysState, NetDeviceAbstractType)) args) | |
{ | |
$ty:((SysState, NetDeviceAbstractType)) data; | |
$ty:(RR (SysState, NetDeviceAbstractType) () ()) ret; | |
- $ty:(PCPULStats) stat; | |
+ struct pcpu_lstats *stats; | |
- /* Ugly ugly type cast below, */ | |
- (args.p2)->lstats = (struct pcpu_lstats *)netdev_alloc_pcpu_stats(*stat); | |
+ /* struct pcpu_lstats is a part of a union in struct net_device */ | |
+ (args.p2)->lstats = netdev_alloc_pcpu_stats(*stats); | |
if (!(args.p2)->lstats) { | |
ret.p2.tag = TAG_ENUM_Error; | |
} else { | |
@@ -107,3 +113,91 @@ inline $ty:((SysState, NetDeviceAbstractType)) netdev_free_pcpu_stats_ac($ty:((S | |
return args; | |
} | |
+ | |
+inline $ty:((SysState, SKBuffAbstractType)) skb_tx_timestamp_ac($ty:((SysState, SKBuffAbstractType)) args) | |
+{ | |
+ skb_tx_timestamp(args.p2); | |
+ | |
+ return args; | |
+} | |
+ | |
+inline $ty:((SysState, SKBuffAbstractType)) skb_orphan_ac($ty:((SysState, SKBuffAbstractType)) args) | |
+{ | |
+ skb_orphan(args.p2); | |
+ | |
+ return args; | |
+} | |
+ | |
+inline $ty:((SysState, SKBuffAbstractType)) skb_dst_force_ac($ty:((SysState, SKBuffAbstractType)) args) | |
+{ | |
+ skb_dst_force(args.p2); | |
+ | |
+ return args; | |
+} | |
+ | |
+inline $ty:((SysState, SKBuffAbstractType, NetDeviceAbstractType)) eth_type_trans_ac($ty:((SysState, SKBuffAbstractType, NetDeviceAbstractType)) args) | |
+{ | |
+ $ty:(SKBuffAbstractType) skb = args.p2; | |
+ | |
+ skb->protocol = eth_type_trans(skb, args.p3); | |
+ | |
+ args.p2 = skb; | |
+ | |
+ return args; | |
+} | |
+ | |
+inline $ty:((SysState, NetDeviceAbstractType, PCPULStatsAbstractType)) this_cpu_ptr_ac($ty:((SysState, NetDeviceAbstractType)) args) | |
+{ | |
+ struct pcpu_lstats *lstats; | |
+ $ty:((SysState, NetDeviceAbstractType, PCPULStatsAbstractType)) ret; | |
+ | |
+ /* it's OK to use per_cpu_ptr() because BHs are off */ | |
+ lstats = this_cpu_ptr(args.p2->lstats); | |
+ | |
+ ret.p1 = args.p1; | |
+ ret.p2 = args.p2; | |
+ ret.p3 = args.p3; | |
+ | |
+ return ret; | |
+} | |
+ | |
+inline $ty:((SKBuffAbstractType!, U64)) get_length_from_skb_ac($ty:((SKBuffAbstractType!)) skbuff) | |
+{ | |
+ $ty:((SKBuffAbstractType, U64)) ret; | |
+ | |
+ ret.p1 = skbuff; | |
+ ret.p2 = skbuff->len; | |
+ | |
+ return ret; | |
+} | |
+ | |
+inline $ty:((R (SysState, PCPULStats) (SysState, PCPULStats)))is_netif_rx_success_ac($ty:((SysState, SKBuffAbstractType!, PCPULStats)) args) | |
+{ | |
+ $ty:((R (SysState, PCPULStats) (SysState, PCPULStats))) ret; | |
+ | |
+ if (likely(netif_rx(args.p2) == NET_RX_SUCCESS)) { | |
+ ret.tag = TAG_ENUM_Success; | |
+ ret.Success.p1 = args.p1; | |
+ ret.Success.p2 = args.p3; | |
+ } else { | |
+ ret.tag = TAG_ENUM_Error; | |
+ ret.Error.p1 = args.p1; | |
+ ret.Error.p2 = args.p3; | |
+ } | |
+ | |
+ return ret; | |
+} | |
+ | |
+inline $ty:((SysState, PCPULStats)) u64_stats_update_begin_ac($ty:((SysState, PCPULStats)) args) | |
+{ | |
+ u64_stats_update_begin(&args.p2->syncp); | |
+ | |
+ return args; | |
+} | |
+ | |
+inline $ty:((SysState, PCPULStats)) u64_stats_update_end_ac($ty:((SysState, PCPULStats)) args) | |
+{ | |
+ u64_stats_update_end(&args.p2->syncp); | |
+ | |
+ return args; | |
+} | |
diff --git a/impl/net/loopback/cogent/plat/linux/wrapper.ac b/impl/net/loopback/cogent/plat/linux/wrapper.ac | |
index b326558c..a0850766 100644 | |
--- a/impl/net/loopback/cogent/plat/linux/wrapper.ac | |
+++ b/impl/net/loopback/cogent/plat/linux/wrapper.ac | |
@@ -18,43 +18,21 @@ $esc:(#include <wrapper.h>) | |
/* Forward declaration of C functions */ | |
static void cg_loopback_setup_ac(struct net_device *dev); | |
+#include <plat/linux/alloc.ac> | |
#include <plat/linux/linux_api.ac> | |
-struct pcpu_lstats { | |
- u64 packets; | |
- u64 bytes; | |
- struct u64_stats_sync syncp; | |
-}; | |
/* The higher levels take care of making this non-reentrant (it's | |
* called with bh's disabled). | |
*/ | |
-static netdev_tx_t cg_loopback_xmit(struct sk_buff *skb, | |
+static netdev_tx_t cg_loopback_xmit(struct sk_buff *sb, | |
struct net_device *dev) | |
{ | |
- struct pcpu_lstats *lb_stats; | |
- int len; | |
- | |
- skb_tx_timestamp(skb); | |
- skb_orphan(skb); | |
- | |
- /* Before queueing this packet to netif_rx(), | |
- * make sure dst is refcounted. | |
- */ | |
- skb_dst_force(skb); | |
- | |
- skb->protocol = eth_type_trans(skb, dev); | |
- | |
- /* it's OK to use per_cpu_ptr() because BHs are off */ | |
- lb_stats = this_cpu_ptr(dev->lstats); | |
+ SysState state; | |
+ $ty:((SysState, SKBuffAbstractType, NetDeviceAbstractType)) args; | |
- len = skb->len; | |
- if (likely(netif_rx(skb) == NET_RX_SUCCESS)) { | |
- u64_stats_update_begin(&lb_stats->syncp); | |
- lb_stats->bytes += len; | |
- lb_stats->packets++; | |
- u64_stats_update_end(&lb_stats->syncp); | |
- } | |
+ /* Ignore the return for now */ | |
+ cg_loopback_xmit_cg(args); | |
return NETDEV_TX_OK; | |
} | |
diff --git a/impl/net/loopback/cogent/src/net.cogent b/impl/net/loopback/cogent/src/net.cogent | |
index 57154a14..0a3aac69 100644 | |
--- a/impl/net/loopback/cogent/src/net.cogent | |
+++ b/impl/net/loopback/cogent/src/net.cogent | |
@@ -16,14 +16,20 @@ include <gum/common/common.cogent> | |
type U64StatsSyncAbstractType | |
type NetAbstractType | |
type NetDeviceAbstractType | |
+type SKBuffAbstractType | |
+type PCPULStatsAbstractType | |
-- CPU stats | |
type PCPULStats = { | |
packets : U64, | |
bytes : U64, | |
- syncp : #U64StatsSyncAbstractType | |
+ syncp : U64StatsSyncAbstractType | |
} | |
+-- Memory management functions | |
+newPCPULStats: SysState -> RR SysState (PCPULStats take (..)) ErrCode | |
+freePCPULStats: (SysState, PCPULStats take (..)) -> SysState | |
+ | |
-- ethtool_ts_info time stamping flags | |
-- defined here: https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/net_tstamp.h#L19 | |
@@ -49,6 +55,15 @@ register_net_dev_ac: (SysState, NetDeviceAbstractType) -> RR (SysState, NetDevic | |
free_netdev_ac: (SysState, NetDeviceAbstractType) -> SysState | |
netdev_alloc_pcpu_stats_ac: (SysState, NetDeviceAbstractType) -> RR (SysState, NetDeviceAbstractType) () () | |
netdev_free_pcpu_stats_ac: (SysState, NetDeviceAbstractType) -> (SysState, NetDeviceAbstractType) | |
+skb_tx_timestamp_ac: (SysState, SKBuffAbstractType) -> (SysState, SKBuffAbstractType) | |
+skb_orphan_ac: (SysState, SKBuffAbstractType) -> (SysState, SKBuffAbstractType) | |
+skb_dst_force_ac: (SysState, SKBuffAbstractType) -> (SysState, SKBuffAbstractType) | |
+eth_type_trans_ac: (SysState, SKBuffAbstractType, NetDeviceAbstractType) -> (SysState, SKBuffAbstractType, NetDeviceAbstractType) | |
+this_cpu_ptr_ac: (SysState, NetDeviceAbstractType, PCPULStatsAbstractType) -> (SysState, NetDeviceAbstractType) | |
+get_length_from_skb_ac: (SKBuffAbstractType!) -> (SKBuffAbstractType!, U64) | |
+is_netif_rx_success_ac: (SysState, SKBuffAbstractType!, PCPULStats) -> R (SysState, PCPULStats) (SysState, PCPULStats) | |
+u64_stats_update_begin_ac: (SysState, PCPULStats) -> (SysState, PCPULStats) | |
+u64_stats_update_end_ac: (SysState, PCPULStats) -> (SysState, PCPULStats) | |
-- cg_loopback_net_init_cg | |
cg_loopback_net_init_cg: (SysState, NetAbstractType) -> RR (SysState, NetAbstractType) () () | |
@@ -86,6 +101,63 @@ get_ts_info_timestamp_flags_cg () = | |
let flags : U32 = flag_SOF_TIMESTAMPING_TX_SOFTWARE .|. flag_SOF_TIMESTAMPING_RX_SOFTWARE .|. flag_SOF_TIMESTAMPING_SOFTWARE | |
in flags | |
+-- set_fields_in_pcpu_lstats | |
set_fields_in_pcpu_lstats: (U64, U64, #U64StatsSyncAbstractType, PCPULStats) -> PCPULStats | |
set_fields_in_pcpu_lstats (packets, bytes, syncp, pcpulstats) = | |
pcpulstats { packets, bytes, syncp } | |
+ | |
+-- update_loopback_stats | |
+update_loopback_stats: (SysState, SKBuffAbstractType!, PCPULStats, PCPULStatsAbstractType) -> (SysState, PCPULStats) | |
+update_loopback_stats (st, skbuff, lbstats, lbstatsabs) = | |
+ is_netif_rx_success_ac(st, skbuff, lbstats) | |
+ | Success (st, lbstats) -> | |
+ let (st, lbstatabs) = u64_stats_update_begin_ac(st, lbstatabs) | |
+ and lbstats {packets, bytes} = lbstats | |
+ and (skbuff, bytes) = get_length_from_skb_ac skbuff | |
+ and packets = packets + 1 | |
+ and lbstats = lbstats {packets, bytes} | |
+ and (st, lbstats) = u64_stats_update_end_ac(st, lbstats, lbstatabs) | |
+ in (st, lbstats) | |
+ | Error (st, lbstats) -> (st, lbstats) | |
+ | |
+-- cg_loopback_xmig_cg | |
+cg_loopback_xmit_cg: (SysState, SKBuffAbstractType, NetDeviceAbstractType) -> (SysState, SKBuffAbstractType, NetDeviceAbstractType) | |
+cg_loopback_xmit_cg (st, skbuff, netdev) = | |
+ newPCPULStats st | |
+ | Succcess (st, lbstats) -> | |
+ let (st, skbuff) = skb_tx_timestamp_ac(st, skbuff) | |
+ and (st, skbuff) = skb_orphan_ac(st, skbuff) | |
+ -- Before queueing this packet to netif_rx(), make sure dst is refcounted | |
+ and (st, skbuff) = skb_dst_force_ac(st, skbuff) | |
+ and (st, skbuff, netdev) = eth_type_trans_ac(st, skbuff, netdev) | |
+ and (st, netdev, lbstatsabs) = this_cpu_ptr_ac(st, netdev) | |
+ and (st, packets, bytes, syncp) = get_lbstats_data(st, lbstatabs) | |
+ and lbstats = lbstats {packets, bytes, syncp} | |
+ and (st, lbstats) = update_loopback_stats(st, skbuff, lbstats, lbstatsabs) !skbuff | |
+ and st = freePCPULStats (st, lbstats) | |
+ in (st, skbuff, netdev) | |
+ | Error st -> (st, skbuff, netdev) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment