Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
loopback patch
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