diff --git a/platform/linux-dpdk/pktio/dpdk.c b/platform/linux-dpdk/pktio/dpdk.c
index a6e2573e5..832ac7acf 100644
--- a/platform/linux-dpdk/pktio/dpdk.c
+++ b/platform/linux-dpdk/pktio/dpdk.c
@@ -99,8 +99,7 @@ static void _dpdk_print_port_mac(uint8_t portid)
 static int input_queues_config_pkt_dpdk(pktio_entry_t *pktio_entry,
 					const odp_pktin_queue_param_t *p)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 	odp_pktin_mode_t mode = pktio_entry->s.param.in_mode;
 
 	/**
@@ -129,8 +128,7 @@ static int input_queues_config_pkt_dpdk(pktio_entry_t *pktio_entry,
 static int output_queues_config_pkt_dpdk(pktio_entry_t *pktio_entry,
 					 const odp_pktout_queue_param_t *p)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 
 	if (p->op_mode == ODP_PKTIO_OP_MT_UNSAFE)
 		pkt_dpdk->lockless_tx = 1;
@@ -147,8 +145,7 @@ static int setup_pkt_dpdk(odp_pktio_t pktio ODP_UNUSED,
 {
 	uint8_t portid = 0;
 	struct rte_eth_dev_info dev_info;
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = NULL;
 	int i;
 
 	if (!_dpdk_netdev_is_valid(netdev)) {
@@ -157,10 +154,14 @@ static int setup_pkt_dpdk(odp_pktio_t pktio ODP_UNUSED,
 		return -1;
 	}
 
-	if (odp_unlikely(pkt_dpdk == NULL)) {
+	pktio_entry->s.ops_data = ODP_OPS_DATA_ALLOC(sizeof(*pkt_dpdk));
+	if (odp_unlikely(pktio_entry->s.ops_data == NULL)) {
 		ODP_ERR("Failed to allocate pktio_ops_dpdk_data_t struct");
 		return -1;
 	}
+	pkt_dpdk = pktio_entry->s.ops_data;
+
+	memset(pkt_dpdk, 0, sizeof(*pkt_dpdk));
 
 	portid = atoi(netdev);
 	pkt_dpdk->portid = portid;
@@ -168,6 +169,7 @@ static int setup_pkt_dpdk(odp_pktio_t pktio ODP_UNUSED,
 	rte_eth_dev_info_get(portid, &dev_info);
 	if (dev_info.driver_name == NULL) {
 		ODP_DBG("No driver found for interface: %s\n", netdev);
+		ODP_OPS_DATA_FREE(pktio_entry->s.ops_data);
 		return -1;
 	}
 	if (!strcmp(dev_info.driver_name, "rte_ixgbe_pmd"))
@@ -191,20 +193,18 @@ static int setup_pkt_dpdk(odp_pktio_t pktio ODP_UNUSED,
 
 static int close_pkt_dpdk(pktio_entry_t *pktio_entry)
 {
-	const pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	const pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 
 	if (pktio_entry->s.state == PKTIO_STATE_STOPPED)
 		rte_eth_dev_close(pkt_dpdk->portid);
 
-	return 0;
+	return ODP_OPS_DATA_FREE(pktio_entry->s.ops_data);
 }
 
 static int start_pkt_dpdk(pktio_entry_t *pktio_entry)
 {
 	int ret, i;
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 	uint8_t portid = pkt_dpdk->portid;
 	int sid = rte_eth_dev_socket_id(pkt_dpdk->portid);
 	int socket_id =  sid < 0 ? 0 : sid;
@@ -312,8 +312,7 @@ static int start_pkt_dpdk(pktio_entry_t *pktio_entry)
 
 static int stop_pkt_dpdk(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 
 	rte_eth_dev_stop(pkt_dpdk->portid);
 	return 0;
@@ -362,8 +361,7 @@ static int recv_pkt_dpdk(pktio_entry_t *pktio_entry, int index,
 			 odp_packet_t pkt_table[], int len)
 {
 	uint16_t nb_rx, i;
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 	odp_packet_t *saved_pkt_table;
 	uint8_t min = pkt_dpdk->min_rx_burst;
 	odp_time_t ts_val;
@@ -479,8 +477,7 @@ static int send_pkt_dpdk(pktio_entry_t *pktio_entry, int index,
 			 const odp_packet_t pkt_table[], int len)
 {
 	int pkts;
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 
 	if (!pkt_dpdk->lockless_tx)
 		odp_ticketlock_lock(&pkt_dpdk->tx_lock[index]);
@@ -532,8 +529,7 @@ static uint32_t _dpdk_vdev_mtu(uint8_t port_id)
 
 static uint32_t mtu_get_pkt_dpdk(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 	uint16_t mtu = 0;
 	int ret;
 
@@ -593,8 +589,7 @@ static int _dpdk_vdev_promisc_mode_set(uint8_t port_id, int enable)
 
 static int promisc_mode_set_pkt_dpdk(pktio_entry_t *pktio_entry,  int enable)
 {
-	const pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	const pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 	uint8_t portid = pkt_dpdk->portid;
 
 	if (enable)
@@ -637,8 +632,7 @@ static int _dpdk_vdev_promisc_mode(uint8_t port_id)
 
 static int promisc_mode_get_pkt_dpdk(pktio_entry_t *pktio_entry)
 {
-	const pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	const pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 	uint8_t portid = pkt_dpdk->portid;
 
 	if (pkt_dpdk->vdev_sysc_promisc)
@@ -649,8 +643,7 @@ static int promisc_mode_get_pkt_dpdk(pktio_entry_t *pktio_entry)
 
 static int mac_get_pkt_dpdk(pktio_entry_t *pktio_entry, void *mac_addr)
 {
-	const pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	const pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 
 	rte_eth_macaddr_get(pkt_dpdk->portid,
 			    (struct ether_addr *)mac_addr);
@@ -660,8 +653,7 @@ static int mac_get_pkt_dpdk(pktio_entry_t *pktio_entry, void *mac_addr)
 static int capability_pkt_dpdk(pktio_entry_t *pktio_entry,
 			       odp_pktio_capability_t *capa)
 {
-	const pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	const pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 
 	*capa = pkt_dpdk->capa;
 	return 0;
@@ -669,8 +661,7 @@ static int capability_pkt_dpdk(pktio_entry_t *pktio_entry,
 
 static int link_status_pkt_dpdk(pktio_entry_t *pktio_entry)
 {
-	const pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	const pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 	struct rte_eth_link link;
 
 	rte_eth_link_get(pkt_dpdk->portid, &link);
@@ -693,8 +684,7 @@ static void stats_convert(struct rte_eth_stats *rte_stats,
 
 static int stats_pkt_dpdk(pktio_entry_t *pktio_entry, odp_pktio_stats_t *stats)
 {
-	const pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	const pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 	int ret;
 	struct rte_eth_stats rte_stats;
 
@@ -712,8 +702,7 @@ static int stats_pkt_dpdk(pktio_entry_t *pktio_entry, odp_pktio_stats_t *stats)
 
 static int stats_reset_pkt_dpdk(pktio_entry_t *pktio_entry)
 {
-	const pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	const pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 
 	rte_eth_stats_reset(pkt_dpdk->portid);
 	return 0;
diff --git a/platform/linux-generic/include/odp_packet_io_internal.h b/platform/linux-generic/include/odp_packet_io_internal.h
index 7df11618e..6912b8519 100644
--- a/platform/linux-generic/include/odp_packet_io_internal.h
+++ b/platform/linux-generic/include/odp_packet_io_internal.h
@@ -43,8 +43,8 @@ typedef union pktio_entry_u pktio_entry_t;
 
 struct pktio_entry {
 	const pktio_ops_module_t *ops;	/**< Implementation specific methods */
-	uint8_t ops_data[ODP_PKTIO_ODPS_DATA_MAX_SIZE]; /**< IO operation
-							specific data */
+	void *ops_data;			/**< IO operation specific data */
+
 	/* These two locks together lock the whole pktio device */
 	odp_ticketlock_t rxl;		/**< RX ticketlock */
 	odp_ticketlock_t txl;		/**< TX ticketlock */
diff --git a/platform/linux-generic/include/odp_pktio_ops_subsystem.h b/platform/linux-generic/include/odp_pktio_ops_subsystem.h
index cb107fed2..f93011e9e 100644
--- a/platform/linux-generic/include/odp_pktio_ops_subsystem.h
+++ b/platform/linux-generic/include/odp_pktio_ops_subsystem.h
@@ -16,6 +16,7 @@ extern "C" {
 
 #include <odp_module.h>
 #include <odp/api/packet_io.h>
+#include <odp_packet_io_pool_access.h>
 
 /* ODP packet IO operations subsystem declaration */
 ODP_SUBSYSTEM_DECLARE(pktio_ops);
@@ -85,13 +86,6 @@ typedef ODP_MODULE_CLASS(pktio_ops) {
 	odp_api_proto(pktio_ops, print) print;
 } pktio_ops_module_t;
 
-/* Maximum size of pktio specific ops data.*/
-#define ODP_PKTIO_ODPS_DATA_MAX_SIZE 80000
-
-/* Extract pktio ops data from pktio entry structure */
-#define odp_ops_data(_p, _mod) \
-	((pktio_ops_ ## _mod ## _data_t *)(uintptr_t)_p->s.ops_data)
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/platform/linux-generic/pktio/dpdk.c b/platform/linux-generic/pktio/dpdk.c
index 4ef111c34..7d39bb1bc 100644
--- a/platform/linux-generic/pktio/dpdk.c
+++ b/platform/linux-generic/pktio/dpdk.c
@@ -382,7 +382,7 @@ static inline int mbuf_to_pkt(pktio_entry_t *pktio_entry,
 			      struct rte_mbuf *mbuf_table[],
 			      uint16_t mbuf_num, odp_time_t *ts)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk = odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 	odp_packet_t pkt;
 	odp_packet_hdr_t *pkt_hdr;
 	uint16_t pkt_len;
@@ -564,8 +564,7 @@ static inline int pkt_to_mbuf(pktio_entry_t *pktio_entry,
 			      struct rte_mbuf *mbuf_table[],
 			      const odp_packet_t pkt_table[], uint16_t num)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 	int i, j;
 	char *data;
 	uint16_t pkt_len;
@@ -609,8 +608,7 @@ static inline int mbuf_to_pkt_zero(pktio_entry_t *pktio_entry,
 				   struct rte_mbuf *mbuf_table[],
 				   uint16_t mbuf_num, odp_time_t *ts)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 	odp_packet_t pkt;
 	odp_packet_hdr_t *pkt_hdr;
 	uint16_t pkt_len;
@@ -683,8 +681,7 @@ static inline int pkt_to_mbuf_zero(pktio_entry_t *pktio_entry,
 				   const odp_packet_t pkt_table[], uint16_t num,
 				   uint16_t *copy_count)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 	odp_pktout_config_opt_t *pktout_cfg = &pktio_entry->s.config.pktout;
 	int i;
 	*copy_count = 0;
@@ -778,8 +775,7 @@ static uint32_t dpdk_vdev_mtu_get(uint8_t port_id)
 
 static uint32_t dpdk_mtu_get(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 	uint32_t mtu = 0;
 
 	if (rte_eth_dev_get_mtu(pkt_dpdk->port_id, (uint16_t *)&mtu))
@@ -872,8 +868,7 @@ static void rss_conf_to_hash_proto(struct rte_eth_rss_conf *rss_conf,
 static int dpdk_setup_port(pktio_entry_t *pktio_entry)
 {
 	int ret;
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 	struct rte_eth_rss_conf rss_conf;
 	uint16_t hw_ip_checksum = 0;
 
@@ -921,8 +916,7 @@ static int dpdk_setup_port(pktio_entry_t *pktio_entry)
 
 static int dpdk_close(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 	unsigned idx;
 	unsigned i, j;
 
@@ -934,7 +928,7 @@ static int dpdk_close(pktio_entry_t *pktio_entry)
 			rte_pktmbuf_free(pkt_dpdk->rx_cache[i].s.pkt[idx++]);
 	}
 
-	return 0;
+	return ODP_OPS_DATA_FREE(pktio_entry->s.ops_data);
 }
 
 static int dpdk_pktio_init(void)
@@ -1088,8 +1082,7 @@ static int dpdk_pktio_term(void)
 static int dpdk_input_queues_config(pktio_entry_t *pktio_entry,
 				    const odp_pktin_queue_param_t *p)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 	odp_pktin_mode_t mode = pktio_entry->s.param.in_mode;
 	odp_bool_t lockless;
 
@@ -1113,8 +1106,7 @@ static int dpdk_input_queues_config(pktio_entry_t *pktio_entry,
 static int dpdk_output_queues_config(pktio_entry_t *pktio_entry,
 				     const odp_pktout_queue_param_t *p)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 	odp_bool_t lockless;
 
 	if (p->op_mode == ODP_PKTIO_OP_MT_UNSAFE)
@@ -1130,8 +1122,7 @@ static int dpdk_output_queues_config(pktio_entry_t *pktio_entry,
 static void dpdk_init_capability(pktio_entry_t *pktio_entry,
 				 struct rte_eth_dev_info *dev_info)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 	odp_pktio_capability_t *capa = &pkt_dpdk->capa;
 	int ptype_cnt;
 	int ptype_l3_ipv4 = 0;
@@ -1208,8 +1199,7 @@ static int dpdk_open(odp_pktio_t id ODP_UNUSED,
 		     const char *netdev,
 		     odp_pool_t pool)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = NULL;
 	struct rte_eth_dev_info dev_info;
 	struct rte_mempool *pkt_pool;
 	char pool_name[RTE_MEMPOOL_NAMESIZE];
@@ -1223,6 +1213,7 @@ static int dpdk_open(odp_pktio_t id ODP_UNUSED,
 
 	if (pool == ODP_POOL_INVALID)
 		return -1;
+
 	pool_entry = pool_entry_from_hdl(pool);
 
 	if (!dpdk_netdev_is_valid(netdev)) {
@@ -1237,10 +1228,12 @@ static int dpdk_open(odp_pktio_t id ODP_UNUSED,
 		dpdk_initialized = 1;
 	}
 
-	if (odp_unlikely(pkt_dpdk == NULL)) {
+	pktio_entry->s.ops_data = ODP_OPS_DATA_ALLOC(sizeof(*pkt_dpdk));
+	if (odp_unlikely(pktio_entry->s.ops_data == NULL)) {
 		ODP_ERR("Failed to allocate pktio_ops_dpdk_data_t struct");
 		return -1;
 	}
+	pkt_dpdk = pktio_entry->s.ops_data;
 
 	/* Init pktio entry */
 	memset(pkt_dpdk, 0, sizeof(*pkt_dpdk));
@@ -1250,6 +1243,7 @@ static int dpdk_open(odp_pktio_t id ODP_UNUSED,
 
 	if (rte_eth_dev_count() == 0) {
 		ODP_ERR("No DPDK ports found\n");
+		ODP_OPS_DATA_FREE(pktio_entry->s.ops_data);
 		return -1;
 	}
 
@@ -1258,6 +1252,7 @@ static int dpdk_open(odp_pktio_t id ODP_UNUSED,
 	mtu = dpdk_mtu_get(pktio_entry);
 	if (mtu == 0) {
 		ODP_ERR("Failed to read interface MTU\n");
+		ODP_OPS_DATA_FREE(pktio_entry->s.ops_data);
 		return -1;
 	}
 	pkt_dpdk->mtu = mtu + _ODP_ETHHDR_LEN;
@@ -1294,6 +1289,7 @@ static int dpdk_open(odp_pktio_t id ODP_UNUSED,
 	}
 	if (pkt_pool == NULL) {
 		ODP_ERR("Cannot init mbuf packet pool\n");
+		ODP_OPS_DATA_FREE(pktio_entry->s.ops_data);
 		return -1;
 	}
 
@@ -1318,8 +1314,7 @@ static int dpdk_open(odp_pktio_t id ODP_UNUSED,
 
 static int dpdk_start(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 	uint8_t port_id = pkt_dpdk->port_id;
 	int ret;
 	unsigned i;
@@ -1370,8 +1365,7 @@ static int dpdk_start(pktio_entry_t *pktio_entry)
 
 static int dpdk_stop(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 
 	rte_eth_dev_stop(pkt_dpdk->port_id);
 
@@ -1381,8 +1375,7 @@ static int dpdk_stop(pktio_entry_t *pktio_entry)
 static int dpdk_recv(pktio_entry_t *pktio_entry, int index,
 		     odp_packet_t pkt_table[], int num)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 	pkt_cache_t *rx_cache = &pkt_dpdk->rx_cache[index];
 	odp_time_t ts_val;
 	odp_time_t *ts = NULL;
@@ -1457,8 +1450,7 @@ static int dpdk_send(pktio_entry_t *pktio_entry, int index,
 		     const odp_packet_t pkt_table[], int num)
 {
 	struct rte_mbuf *tx_mbufs[num];
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 	uint16_t copy_count = 0;
 	int tx_pkts;
 	int i;
@@ -1521,8 +1513,7 @@ static int dpdk_send(pktio_entry_t *pktio_entry, int index,
 
 static int dpdk_mac_addr_get(pktio_entry_t *pktio_entry, void *mac_addr)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 
 	rte_eth_macaddr_get(pkt_dpdk->port_id,
 			    (struct ether_addr *)mac_addr);
@@ -1531,8 +1522,7 @@ static int dpdk_mac_addr_get(pktio_entry_t *pktio_entry, void *mac_addr)
 
 static int dpdk_promisc_mode_set(pktio_entry_t *pktio_entry, odp_bool_t enable)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 	uint8_t port_id = pkt_dpdk->port_id;
 
 	if (pkt_dpdk->vdev_sysc_promisc)
@@ -1548,8 +1538,7 @@ static int dpdk_promisc_mode_set(pktio_entry_t *pktio_entry, odp_bool_t enable)
 
 static int dpdk_promisc_mode_get(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 	uint8_t port_id = pkt_dpdk->port_id;
 
 	if (pkt_dpdk->vdev_sysc_promisc)
@@ -1561,8 +1550,7 @@ static int dpdk_promisc_mode_get(pktio_entry_t *pktio_entry)
 static int dpdk_capability(pktio_entry_t *pktio_entry,
 			   odp_pktio_capability_t *capa)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 
 	*capa = pkt_dpdk->capa;
 	return 0;
@@ -1570,8 +1558,7 @@ static int dpdk_capability(pktio_entry_t *pktio_entry,
 
 static int dpdk_link_status(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 	struct rte_eth_link link;
 
 	memset(&link, 0, sizeof(struct rte_eth_link));
@@ -1595,8 +1582,7 @@ static void stats_convert(const struct rte_eth_stats *rte_stats,
 
 static int dpdk_stats(pktio_entry_t *pktio_entry, odp_pktio_stats_t *stats)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 	int ret;
 	struct rte_eth_stats rte_stats;
 
@@ -1611,8 +1597,7 @@ static int dpdk_stats(pktio_entry_t *pktio_entry, odp_pktio_stats_t *stats)
 
 static int dpdk_stats_reset(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_dpdk_data_t *pkt_dpdk =
-		odp_ops_data(pktio_entry, dpdk);
+	pktio_ops_dpdk_data_t *pkt_dpdk = pktio_entry->s.ops_data;
 
 	rte_eth_stats_reset(pkt_dpdk->port_id);
 	return 0;
diff --git a/platform/linux-generic/pktio/ipc.c b/platform/linux-generic/pktio/ipc.c
index 5ab957403..9d928c72a 100644
--- a/platform/linux-generic/pktio/ipc.c
+++ b/platform/linux-generic/pktio/ipc.c
@@ -49,7 +49,7 @@ static const char *_ipc_odp_buffer_pool_shm_name(odp_pool_t pool_hdl)
 
 static int _ipc_master_start(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_ipc_data_t *pkt_ipc = odp_ops_data(pktio_entry, ipc);
+	pktio_ops_ipc_data_t *pkt_ipc = pktio_entry->s.ops_data;
 	struct pktio_info *pinfo = pkt_ipc->pinfo;
 	odp_shm_t shm;
 
@@ -78,7 +78,7 @@ static int _ipc_init_master(pktio_entry_t *pktio_entry,
 			    const char *dev,
 			    odp_pool_t pool_hdl)
 {
-	pktio_ops_ipc_data_t *pkt_ipc = odp_ops_data(pktio_entry, ipc);
+	pktio_ops_ipc_data_t *pkt_ipc = pktio_entry->s.ops_data;
 	char ipc_shm_name[ODP_POOL_NAME_LEN + sizeof("_m_prod")];
 	pool_t *pool;
 	struct pktio_info *pinfo;
@@ -230,7 +230,7 @@ static int _ipc_init_slave(const char *dev,
 			   pktio_entry_t *pktio_entry,
 			   odp_pool_t pool)
 {
-	pktio_ops_ipc_data_t *pkt_ipc = odp_ops_data(pktio_entry, ipc);
+	pktio_ops_ipc_data_t *pkt_ipc = pktio_entry->s.ops_data;
 
 	if (strlen(dev) > (ODP_POOL_NAME_LEN - sizeof("_slave_r")))
 		ODP_ABORT("too big ipc name\n");
@@ -241,7 +241,7 @@ static int _ipc_init_slave(const char *dev,
 
 static int _ipc_slave_start(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_ipc_data_t *pkt_ipc = odp_ops_data(pktio_entry, ipc);
+	pktio_ops_ipc_data_t *pkt_ipc = pktio_entry->s.ops_data;
 	char ipc_shm_name[ODP_POOL_NAME_LEN + sizeof("_slave_r")];
 	struct pktio_info *pinfo;
 	odp_shm_t shm;
@@ -343,7 +343,7 @@ static int ipc_pktio_open(odp_pktio_t id ODP_UNUSED,
 	char name[ODP_POOL_NAME_LEN + sizeof("_info")];
 	char tail[ODP_POOL_NAME_LEN];
 	odp_shm_t shm;
-	pktio_ops_ipc_data_t *pkt_ipc = odp_ops_data(pktio_entry, ipc);
+	pktio_ops_ipc_data_t *pkt_ipc;
 
 	ODP_STATIC_ASSERT(ODP_POOL_NAME_LEN == _RING_NAMESIZE,
 			  "mismatch pool and ring name arrays");
@@ -351,6 +351,15 @@ static int ipc_pktio_open(odp_pktio_t id ODP_UNUSED,
 	if (strncmp(dev, "ipc", 3))
 		return -1;
 
+	pktio_entry->s.ops_data = ODP_OPS_DATA_ALLOC(sizeof(*pkt_ipc));
+	if (odp_unlikely(pktio_entry->s.ops_data == NULL)) {
+		ODP_ERR("Failed to allocate pktio_ops_ipc_data_t struct");
+		return -1;
+	}
+
+	pkt_ipc = pktio_entry->s.ops_data;
+	memset(pkt_ipc, 0, sizeof(*pkt_ipc));
+
 	odp_atomic_init_u32(&pkt_ipc->ready, 0);
 
 	pkt_ipc->rx.cache = _ring_create("ipc_rx_cache",
@@ -364,12 +373,15 @@ static int ipc_pktio_open(odp_pktio_t id ODP_UNUSED,
 		snprintf(name, sizeof(name), "ipc:%s_info", tail);
 		IPC_ODP_DBG("lookup for name %s for pid %d\n", name, pid);
 		shm = odp_shm_import(name, pid, name);
-		if (ODP_SHM_INVALID == shm)
+		if (ODP_SHM_INVALID == shm) {
+			ODP_OPS_DATA_FREE(pktio_entry->s.ops_data);
 			return -1;
+		}
 		pinfo = odp_shm_addr(shm);
 
 		if (!pinfo->master.init_done) {
 			odp_shm_free(shm);
+			ODP_OPS_DATA_FREE(pktio_entry->s.ops_data);
 			return -1;
 		}
 		pkt_ipc->pinfo = pinfo;
@@ -384,6 +396,7 @@ static int ipc_pktio_open(odp_pktio_t id ODP_UNUSED,
 				      _ODP_ISHM_EXPORT | _ODP_ISHM_LOCK);
 		if (ODP_SHM_INVALID == shm) {
 			ODP_ERR("can not create shm %s\n", name);
+			ODP_OPS_DATA_FREE(pktio_entry->s.ops_data);
 			return -1;
 		}
 
@@ -396,12 +409,14 @@ static int ipc_pktio_open(odp_pktio_t id ODP_UNUSED,
 		ret = _ipc_init_master(pktio_entry, dev, pool);
 	}
 
+	if (ret)
+		ODP_OPS_DATA_FREE(pktio_entry->s.ops_data);
 	return ret;
 }
 
 static void _ipc_free_ring_packets(pktio_entry_t *pktio_entry, _ring_t *r)
 {
-	pktio_ops_ipc_data_t *pkt_ipc = odp_ops_data(pktio_entry, ipc);
+	pktio_ops_ipc_data_t *pkt_ipc = pktio_entry->s.ops_data;
 	uintptr_t offsets[PKTIO_IPC_ENTRIES];
 	int ret;
 	void **rbuf_p;
@@ -437,7 +452,7 @@ static void _ipc_free_ring_packets(pktio_entry_t *pktio_entry, _ring_t *r)
 static int ipc_pktio_recv_lockless(pktio_entry_t *pktio_entry,
 				   odp_packet_t pkt_table[], int len)
 {
-	pktio_ops_ipc_data_t *pkt_ipc = odp_ops_data(pktio_entry, ipc);
+	pktio_ops_ipc_data_t *pkt_ipc = pktio_entry->s.ops_data;
 	int pkts = 0;
 	int i;
 	_ring_t *r;
@@ -590,7 +605,7 @@ static int ipc_pktio_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 static int ipc_pktio_send_lockless(pktio_entry_t *pktio_entry,
 				   const odp_packet_t pkt_table[], int len)
 {
-	pktio_ops_ipc_data_t *pkt_ipc = odp_ops_data(pktio_entry, ipc);
+	pktio_ops_ipc_data_t *pkt_ipc = pktio_entry->s.ops_data;
 	_ring_t *r;
 	void **rbuf_p;
 	int ret;
@@ -703,7 +718,7 @@ static int ipc_mac_addr_get(pktio_entry_t *pktio_entry ODP_UNUSED,
 
 static int ipc_start(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_ipc_data_t *pkt_ipc = odp_ops_data(pktio_entry, ipc);
+	pktio_ops_ipc_data_t *pkt_ipc = pktio_entry->s.ops_data;
 	uint32_t ready = odp_atomic_load_u32(&pkt_ipc->ready);
 
 	if (ready) {
@@ -719,7 +734,7 @@ static int ipc_start(pktio_entry_t *pktio_entry)
 
 static int ipc_stop(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_ipc_data_t *pkt_ipc = odp_ops_data(pktio_entry, ipc);
+	pktio_ops_ipc_data_t *pkt_ipc = pktio_entry->s.ops_data;
 	unsigned tx_send = 0, tx_free = 0;
 
 	odp_atomic_store_u32(&pkt_ipc->ready, 0);
@@ -746,7 +761,7 @@ static int ipc_stop(pktio_entry_t *pktio_entry)
 
 static int ipc_close(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_ipc_data_t *pkt_ipc = odp_ops_data(pktio_entry, ipc);
+	pktio_ops_ipc_data_t *pkt_ipc = pktio_entry->s.ops_data;
 	char ipc_shm_name[ODP_POOL_NAME_LEN + sizeof("_m_prod")];
 	char *dev = pktio_entry->s.name;
 	char name[ODP_POOL_NAME_LEN];
@@ -776,7 +791,7 @@ static int ipc_close(pktio_entry_t *pktio_entry)
 	_ring_destroy(ipc_shm_name);
 	_ring_destroy("ipc_rx_cache");
 
-	return 0;
+	return ODP_OPS_DATA_FREE(pktio_entry->s.ops_data);
 }
 
 static int ipc_pktio_init_global(void)
diff --git a/platform/linux-generic/pktio/loopback.c b/platform/linux-generic/pktio/loopback.c
index 60bee5913..ff08364a2 100644
--- a/platform/linux-generic/pktio/loopback.c
+++ b/platform/linux-generic/pktio/loopback.c
@@ -32,20 +32,30 @@ static int loopback_stats_reset(pktio_entry_t *pktio_entry);
 static int loopback_open(odp_pktio_t id, pktio_entry_t *pktio_entry,
 			 const char *devname, odp_pool_t pool ODP_UNUSED)
 {
-	pktio_ops_loopback_data_t *pkt_lbk =
-		odp_ops_data(pktio_entry, loopback);
+	pktio_ops_loopback_data_t *pkt_lbk = NULL;
 
 	if (strcmp(devname, "loop"))
 		return -1;
 
+	pktio_entry->s.ops_data = ODP_OPS_DATA_ALLOC(sizeof(*pkt_lbk));
+	if (odp_unlikely(pktio_entry->s.ops_data == NULL)) {
+		ODP_ERR("Failed to allocate pktio_ops_loopback_data_t struct");
+		return -1;
+	}
+
+	pkt_lbk = pktio_entry->s.ops_data;
+	memset(pkt_lbk, 0, sizeof(*pkt_lbk));
+
 	char loopq_name[ODP_QUEUE_NAME_LEN];
 
 	snprintf(loopq_name, sizeof(loopq_name), "%" PRIu64 "-pktio_loopq",
 		 odp_pktio_to_u64(id));
 	pkt_lbk->loopq = odp_queue_create(loopq_name, NULL);
 
-	if (pkt_lbk->loopq == ODP_QUEUE_INVALID)
+	if (pkt_lbk->loopq == ODP_QUEUE_INVALID) {
+		ODP_OPS_DATA_FREE(pktio_entry->s.ops_data);
 		return -1;
+	}
 
 	loopback_stats_reset(pktio_entry);
 
@@ -54,10 +64,16 @@ static int loopback_open(odp_pktio_t id, pktio_entry_t *pktio_entry,
 
 static int loopback_close(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_loopback_data_t *pkt_lbk =
-		odp_ops_data(pktio_entry, loopback);
+	int result = 0;
+	pktio_ops_loopback_data_t *pkt_lbk = pktio_entry->s.ops_data;
+
+	if (odp_queue_destroy(pkt_lbk->loopq))
+		result = -1;
+
+	if (ODP_OPS_DATA_FREE(pktio_entry->s.ops_data))
+		result = -1;
 
-	return odp_queue_destroy(pkt_lbk->loopq);
+	return result;
 }
 
 static int loopback_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
@@ -72,8 +88,7 @@ static int loopback_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 	odp_time_t *ts = NULL;
 	int num_rx = 0;
 	int failed = 0;
-	pktio_ops_loopback_data_t *pkt_lbk =
-		odp_ops_data(pktio_entry, loopback);
+	pktio_ops_loopback_data_t *pkt_lbk = pktio_entry->s.ops_data;
 
 	if (odp_unlikely(len > QUEUE_MULTI_MAX))
 		len = QUEUE_MULTI_MAX;
@@ -170,8 +185,7 @@ static int loopback_send(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 	int i;
 	int ret;
 	uint32_t bytes = 0;
-	pktio_ops_loopback_data_t *pkt_lbk =
-		odp_ops_data(pktio_entry, loopback);
+	pktio_ops_loopback_data_t *pkt_lbk = pktio_entry->s.ops_data;
 
 	if (odp_unlikely(len > QUEUE_MULTI_MAX))
 		len = QUEUE_MULTI_MAX;
@@ -255,8 +269,7 @@ static int loopback_capability(pktio_entry_t *pktio_entry ODP_UNUSED,
 static int loopback_promisc_mode_set(pktio_entry_t *pktio_entry,
 				     odp_bool_t enable)
 {
-	pktio_ops_loopback_data_t *pkt_lbk =
-		odp_ops_data(pktio_entry, loopback);
+	pktio_ops_loopback_data_t *pkt_lbk = pktio_entry->s.ops_data;
 
 	pkt_lbk->promisc = enable;
 	return 0;
@@ -264,8 +277,7 @@ static int loopback_promisc_mode_set(pktio_entry_t *pktio_entry,
 
 static int loopback_promisc_mode_get(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_loopback_data_t *pkt_lbk =
-		odp_ops_data(pktio_entry, loopback);
+	pktio_ops_loopback_data_t *pkt_lbk = pktio_entry->s.ops_data;
 
 	return pkt_lbk->promisc ? 1 : 0;
 }
diff --git a/platform/linux-generic/pktio/netmap.c b/platform/linux-generic/pktio/netmap.c
index 29c449e40..2631c816d 100644
--- a/platform/linux-generic/pktio/netmap.c
+++ b/platform/linux-generic/pktio/netmap.c
@@ -50,8 +50,7 @@ static int netmap_stats_reset(pktio_entry_t *pktio_entry);
 static int netmap_do_ioctl(pktio_entry_t *pktio_entry, unsigned long cmd,
 			   int subcmd)
 {
-	pktio_ops_netmap_data_t *pkt_nm =
-		odp_ops_data(pktio_entry, netmap);
+	pktio_ops_netmap_data_t *pkt_nm = pktio_entry->s.ops_data;
 	struct ethtool_value eval;
 	struct ifreq ifr;
 	int err;
@@ -138,8 +137,7 @@ static inline void map_netmap_rings(netmap_ring_t *rings,
 static int netmap_input_queues_config(pktio_entry_t *pktio_entry,
 				      const odp_pktin_queue_param_t *p)
 {
-	pktio_ops_netmap_data_t *pkt_nm =
-		odp_ops_data(pktio_entry, netmap);
+	pktio_ops_netmap_data_t *pkt_nm = pktio_entry->s.ops_data;
 	odp_pktin_mode_t mode = pktio_entry->s.param.in_mode;
 	unsigned num_queues = p->num_queues;
 	odp_bool_t lockless;
@@ -167,8 +165,7 @@ static int netmap_input_queues_config(pktio_entry_t *pktio_entry,
 static int netmap_output_queues_config(pktio_entry_t *pktio_entry,
 				       const odp_pktout_queue_param_t *p)
 {
-	pktio_ops_netmap_data_t *pkt_nm =
-		odp_ops_data(pktio_entry, netmap);
+	pktio_ops_netmap_data_t *pkt_nm = pktio_entry->s.ops_data;
 
 	pkt_nm->lockless_tx = (p->op_mode == ODP_PKTIO_OP_MT_UNSAFE);
 
@@ -185,8 +182,7 @@ static int netmap_output_queues_config(pktio_entry_t *pktio_entry,
 static inline void netmap_close_descriptors(pktio_entry_t *pktio_entry)
 {
 	int i, j;
-	pktio_ops_netmap_data_t *pkt_nm =
-		odp_ops_data(pktio_entry, netmap);
+	pktio_ops_netmap_data_t *pkt_nm = pktio_entry->s.ops_data;
 
 	for (i = 0; i < PKTIO_MAX_QUEUES; i++) {
 		for (j = 0; j < NM_MAX_DESC; j++) {
@@ -209,23 +205,30 @@ static inline void netmap_close_descriptors(pktio_entry_t *pktio_entry)
 
 static int netmap_close(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_netmap_data_t *pkt_nm =
-		odp_ops_data(pktio_entry, netmap);
+	int status = 0;
+	pktio_ops_netmap_data_t *pkt_nm = pktio_entry->s.ops_data;
 
 	netmap_close_descriptors(pktio_entry);
 
 	if (pkt_nm->sockfd != -1 && close(pkt_nm->sockfd) != 0) {
 		__odp_errno = errno;
 		ODP_ERR("close(sockfd): %s\n", strerror(errno));
-		return -1;
+
+		status = -1;
 	}
-	return 0;
+
+	if (ODP_OPS_DATA_FREE(pktio_entry->s.ops_data)) {
+		ODP_ERR("ops_data_free(netmap) failed\n");
+
+		status = -1;
+	}
+
+	return status;
 }
 
 static int netmap_link_status(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_netmap_data_t *pkt_nm =
-		odp_ops_data(pktio_entry, netmap);
+	pktio_ops_netmap_data_t *pkt_nm = pktio_entry->s.ops_data;
 
 	if (pkt_nm->is_virtual)
 		return 1;
@@ -246,8 +249,7 @@ static inline int netmap_wait_for_link(pktio_entry_t *pktio_entry)
 {
 	int i;
 	int ret;
-	pktio_ops_netmap_data_t *pkt_nm =
-		odp_ops_data(pktio_entry, netmap);
+	pktio_ops_netmap_data_t *pkt_nm = pktio_entry->s.ops_data;
 
 	/* Wait for the link to come up */
 	for (i = 0; i <= NM_WAIT_TIMEOUT; i++) {
@@ -275,8 +277,7 @@ static inline int netmap_wait_for_link(pktio_entry_t *pktio_entry)
  */
 static void netmap_init_capability(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_netmap_data_t *pkt_nm =
-		odp_ops_data(pktio_entry, netmap);
+	pktio_ops_netmap_data_t *pkt_nm = pktio_entry->s.ops_data;
 	odp_pktio_capability_t *capa = &pkt_nm->capa;
 
 	memset(&pkt_nm->capa, 0, sizeof(odp_pktio_capability_t));
@@ -343,8 +344,7 @@ static int netmap_open(odp_pktio_t id ODP_UNUSED, pktio_entry_t *pktio_entry,
 	const char *prefix;
 	uint32_t mtu;
 	uint32_t buf_size;
-	pktio_ops_netmap_data_t *pkt_nm =
-		odp_ops_data(pktio_entry, netmap);
+	pktio_ops_netmap_data_t *pkt_nm = NULL;
 	struct nm_desc *desc;
 	struct netmap_ring *ring;
 	odp_pktin_hash_proto_t hash_proto;
@@ -356,6 +356,13 @@ static int netmap_open(odp_pktio_t id ODP_UNUSED, pktio_entry_t *pktio_entry,
 	if (pool == ODP_POOL_INVALID)
 		return -1;
 
+	pktio_entry->s.ops_data = ODP_OPS_DATA_ALLOC(sizeof(*pkt_nm));
+	if (odp_unlikely(pktio_entry->s.ops_data == NULL)) {
+		ODP_ERR("Failed to allocate pktio_ops_netmap_data_t struct");
+		return -1;
+	}
+	pkt_nm = pktio_entry->s.ops_data;
+
 	/* Init pktio entry */
 	memset(pkt_nm, 0, sizeof(*pkt_nm));
 	pkt_nm->sockfd = -1;
@@ -476,8 +483,7 @@ static int netmap_open(odp_pktio_t id ODP_UNUSED, pktio_entry_t *pktio_entry,
 
 static int netmap_start(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_netmap_data_t *pkt_nm =
-		odp_ops_data(pktio_entry, netmap);
+	pktio_ops_netmap_data_t *pkt_nm = pktio_entry->s.ops_data;
 	netmap_ring_t *desc_ring;
 	struct nm_desc *desc_ptr;
 	unsigned i;
@@ -633,8 +639,7 @@ static inline int netmap_pkt_to_odp(pktio_entry_t *pktio_entry,
 				    netmap_slot_t slot_tbl[], int16_t slot_num,
 				    odp_time_t *ts)
 {
-	pktio_ops_netmap_data_t *pkt_nm =
-		odp_ops_data(pktio_entry, netmap);
+	pktio_ops_netmap_data_t *pkt_nm = pktio_entry->s.ops_data;
 	odp_packet_t pkt;
 	odp_pool_t pool = pkt_nm->pool;
 	odp_packet_hdr_t *pkt_hdr;
@@ -750,8 +755,7 @@ static int netmap_recv(pktio_entry_t *pktio_entry, int index,
 		       odp_packet_t pkt_table[], int num)
 {
 	struct nm_desc *desc;
-	pktio_ops_netmap_data_t *pkt_nm =
-		odp_ops_data(pktio_entry, netmap);
+	pktio_ops_netmap_data_t *pkt_nm = pktio_entry->s.ops_data;
 	unsigned first_desc_id = pkt_nm->rx_desc_ring[index].s.first;
 	unsigned last_desc_id = pkt_nm->rx_desc_ring[index].s.last;
 	unsigned desc_id;
@@ -804,8 +808,7 @@ static int netmap_recv(pktio_entry_t *pktio_entry, int index,
 static int netmap_send(pktio_entry_t *pktio_entry, int index,
 		       const odp_packet_t pkt_table[], int num)
 {
-	pktio_ops_netmap_data_t *pkt_nm =
-		odp_ops_data(pktio_entry, netmap);
+	pktio_ops_netmap_data_t *pkt_nm = pktio_entry->s.ops_data;
 	struct pollfd polld;
 	struct nm_desc *desc;
 	struct netmap_ring *ring;
@@ -880,8 +883,7 @@ static int netmap_send(pktio_entry_t *pktio_entry, int index,
 
 static int netmap_mac_addr_get(pktio_entry_t *pktio_entry, void *mac_addr)
 {
-	pktio_ops_netmap_data_t *pkt_nm =
-		odp_ops_data(pktio_entry, netmap);
+	pktio_ops_netmap_data_t *pkt_nm = pktio_entry->s.ops_data;
 
 	memcpy(mac_addr, pkt_nm->if_mac, ETH_ALEN);
 	return ETH_ALEN;
@@ -889,8 +891,7 @@ static int netmap_mac_addr_get(pktio_entry_t *pktio_entry, void *mac_addr)
 
 static uint32_t netmap_mtu_get(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_netmap_data_t *pkt_nm =
-		odp_ops_data(pktio_entry, netmap);
+	pktio_ops_netmap_data_t *pkt_nm = pktio_entry->s.ops_data;
 
 	return pkt_nm->mtu;
 }
@@ -898,8 +899,7 @@ static uint32_t netmap_mtu_get(pktio_entry_t *pktio_entry)
 static int netmap_promisc_mode_set(pktio_entry_t *pktio_entry,
 				   odp_bool_t enable)
 {
-	pktio_ops_netmap_data_t *pkt_nm =
-		odp_ops_data(pktio_entry, netmap);
+	pktio_ops_netmap_data_t *pkt_nm = pktio_entry->s.ops_data;
 
 	if (pkt_nm->is_virtual) {
 		__odp_errno = ENOTSUP;
@@ -911,8 +911,7 @@ static int netmap_promisc_mode_set(pktio_entry_t *pktio_entry,
 
 static int netmap_promisc_mode_get(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_netmap_data_t *pkt_nm =
-		odp_ops_data(pktio_entry, netmap);
+	pktio_ops_netmap_data_t *pkt_nm = pktio_entry->s.ops_data;
 
 	if (pkt_nm->is_virtual)
 		return 0;
@@ -923,8 +922,7 @@ static int netmap_promisc_mode_get(pktio_entry_t *pktio_entry)
 static int netmap_capability(pktio_entry_t *pktio_entry,
 			     odp_pktio_capability_t *capa)
 {
-	pktio_ops_netmap_data_t *pkt_nm =
-		odp_ops_data(pktio_entry, netmap);
+	pktio_ops_netmap_data_t *pkt_nm = pktio_entry->s.ops_data;
 
 	*capa = pkt_nm->capa;
 	return 0;
@@ -933,8 +931,7 @@ static int netmap_capability(pktio_entry_t *pktio_entry,
 static int netmap_stats(pktio_entry_t *pktio_entry,
 			odp_pktio_stats_t *stats)
 {
-	pktio_ops_netmap_data_t *pkt_nm =
-		odp_ops_data(pktio_entry, netmap);
+	pktio_ops_netmap_data_t *pkt_nm = pktio_entry->s.ops_data;
 
 	if (pktio_entry->s.stats_type == STATS_UNSUPPORTED) {
 		memset(stats, 0, sizeof(*stats));
@@ -947,8 +944,7 @@ static int netmap_stats(pktio_entry_t *pktio_entry,
 
 static int netmap_stats_reset(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_netmap_data_t *pkt_nm =
-		odp_ops_data(pktio_entry, netmap);
+	pktio_ops_netmap_data_t *pkt_nm = pktio_entry->s.ops_data;
 
 	if (pktio_entry->s.stats_type == STATS_UNSUPPORTED) {
 		memset(&pktio_entry->s.stats, 0,
@@ -962,8 +958,7 @@ static int netmap_stats_reset(pktio_entry_t *pktio_entry)
 static void netmap_print(pktio_entry_t *pktio_entry)
 {
 	odp_pktin_hash_proto_t hash_proto;
-	pktio_ops_netmap_data_t *pkt_nm =
-		odp_ops_data(pktio_entry, netmap);
+	pktio_ops_netmap_data_t *pkt_nm = pktio_entry->s.ops_data;
 
 	if (rss_conf_get_fd(pkt_nm->sockfd, pkt_nm->if_name, &hash_proto))
 		rss_conf_print(&hash_proto);
diff --git a/platform/linux-generic/pktio/pcap.c b/platform/linux-generic/pktio/pcap.c
index 5bfaeef0e..f3f000574 100644
--- a/platform/linux-generic/pktio/pcap.c
+++ b/platform/linux-generic/pktio/pcap.c
@@ -140,10 +140,17 @@ static int _pcapif_init_tx(pktio_ops_pcap_data_t *pcap)
 static int pcapif_init(odp_pktio_t id ODP_UNUSED, pktio_entry_t *pktio_entry,
 		       const char *devname, odp_pool_t pool)
 {
-	pktio_ops_pcap_data_t *pcap = odp_ops_data(pktio_entry, pcap);
+	pktio_ops_pcap_data_t *pcap = NULL;
 	int ret;
 
-	memset(pcap, 0, sizeof(pktio_ops_pcap_data_t));
+	pktio_entry->s.ops_data = ODP_OPS_DATA_ALLOC(sizeof(*pcap));
+	if (odp_unlikely(pktio_entry->s.ops_data == NULL)) {
+		ODP_ERR("Failed to allocate pktio_ops_pcap_data_t struct");
+		return -1;
+	}
+	pcap = pktio_entry->s.ops_data;
+
+	memset(pcap, 0, sizeof(*pcap));
 	pcap->loop_cnt = 1;
 	pcap->loops = 1;
 	pcap->pool = pool;
@@ -162,12 +169,15 @@ static int pcapif_init(odp_pktio_t id ODP_UNUSED, pktio_entry_t *pktio_entry,
 
 	(void)pcapif_stats_reset(pktio_entry);
 
+	if (ret)
+		ODP_OPS_DATA_FREE(pktio_entry->s.ops_data);
+
 	return ret;
 }
 
 static int pcapif_close(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_pcap_data_t *pcap = odp_ops_data(pktio_entry, pcap);
+	pktio_ops_pcap_data_t *pcap = pktio_entry->s.ops_data;
 
 	if (pcap->tx_dump)
 		pcap_dump_close(pcap->tx_dump);
@@ -182,7 +192,7 @@ static int pcapif_close(pktio_entry_t *pktio_entry)
 	free(pcap->fname_rx);
 	free(pcap->fname_tx);
 
-	return 0;
+	return ODP_OPS_DATA_FREE(pktio_entry->s.ops_data);
 }
 
 static int _pcapif_reopen(pktio_ops_pcap_data_t *pcap)
@@ -214,7 +224,7 @@ static int pcapif_recv_pkt(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 	odp_packet_t pkt;
 	odp_packet_hdr_t *pkt_hdr;
 	uint32_t pkt_len;
-	pktio_ops_pcap_data_t *pcap = odp_ops_data(pktio_entry, pcap);
+	pktio_ops_pcap_data_t *pcap = pktio_entry->s.ops_data;
 	odp_time_t ts_val;
 	odp_time_t *ts = NULL;
 
@@ -297,7 +307,7 @@ static int _pcapif_dump_pkt(pktio_ops_pcap_data_t *pcap, odp_packet_t pkt)
 static int pcapif_send_pkt(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 			   const odp_packet_t pkts[], int len)
 {
-	pktio_ops_pcap_data_t *pcap = odp_ops_data(pktio_entry, pcap);
+	pktio_ops_pcap_data_t *pcap = pktio_entry->s.ops_data;
 	int i;
 
 	odp_ticketlock_lock(&pktio_entry->s.txl);
@@ -365,7 +375,7 @@ static int pcapif_promisc_mode_set(pktio_entry_t *pktio_entry,
 {
 	char filter_exp[64] = {0};
 	struct bpf_program bpf;
-	pktio_ops_pcap_data_t *pcap = odp_ops_data(pktio_entry, pcap);
+	pktio_ops_pcap_data_t *pcap = pktio_entry->s.ops_data;
 
 	if (!pcap->rx) {
 		pcap->promisc = enable;
@@ -405,7 +415,7 @@ static int pcapif_promisc_mode_set(pktio_entry_t *pktio_entry,
 
 static int pcapif_promisc_mode_get(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_pcap_data_t *pcap = odp_ops_data(pktio_entry, pcap);
+	pktio_ops_pcap_data_t *pcap = pktio_entry->s.ops_data;
 
 	return pcap->promisc;
 }
diff --git a/platform/linux-generic/pktio/socket.c b/platform/linux-generic/pktio/socket.c
index d9f85b29a..7e0485b99 100644
--- a/platform/linux-generic/pktio/socket.c
+++ b/platform/linux-generic/pktio/socket.c
@@ -110,16 +110,21 @@ int sendmmsg(int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
  */
 static int sock_close(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_socket_data_t *pkt_sock =
-		odp_ops_data(pktio_entry, socket);
+	int result = 0;
+	pktio_ops_socket_data_t *pkt_sock = pktio_entry->s.ops_data;
 
 	if (pkt_sock->sockfd != -1 && close(pkt_sock->sockfd) != 0) {
 		__odp_errno = errno;
 		ODP_ERR("close(sockfd): %s\n", strerror(errno));
-		return -1;
+		result = -1;
 	}
 
-	return 0;
+	if (ODP_OPS_DATA_FREE(pktio_entry->s.ops_data)) {
+		ODP_ERR("ops_data_free(socket) failed\n");
+		result = -1;
+	}
+
+	return result;
 }
 
 /*
@@ -134,18 +139,25 @@ static int sock_setup_pkt(pktio_entry_t *pktio_entry, const char *netdev,
 	struct ifreq ethreq;
 	struct sockaddr_ll sa_ll;
 	char shm_name[ODP_SHM_NAME_LEN];
-	pktio_ops_socket_data_t *pkt_sock =
-		odp_ops_data(pktio_entry, socket);
+	pktio_ops_socket_data_t *pkt_sock = NULL;
 	odp_pktio_stats_t cur_stats;
 
+	if (pool == ODP_POOL_INVALID)
+		return -1;
+
+	pktio_entry->s.ops_data = ODP_OPS_DATA_ALLOC(sizeof(*pkt_sock));
+	if (odp_unlikely(pktio_entry->s.ops_data == NULL)) {
+		ODP_ERR("Failed to allocate pktio_ops_socket_data_t struct");
+		return -1;
+	}
+	pkt_sock = pktio_entry->s.ops_data;
+
 	/* Init pktio entry */
 	memset(pkt_sock, 0, sizeof(*pkt_sock));
 	/* set sockfd to -1, because a valid socked might be initialized to 0 */
 	pkt_sock->sockfd = -1;
-
-	if (pool == ODP_POOL_INVALID)
-		return -1;
 	pkt_sock->pool = pool;
+
 	snprintf(shm_name, ODP_SHM_NAME_LEN, "%s-%s", "pktio", netdev);
 	shm_name[ODP_SHM_NAME_LEN - 1] = '\0';
 
@@ -212,7 +224,6 @@ static int sock_setup_pkt(pktio_entry_t *pktio_entry, const char *netdev,
 
 error:
 	sock_close(pktio_entry);
-
 	return -1;
 }
 
@@ -259,8 +270,7 @@ static uint32_t _rx_pkt_to_iovec(odp_packet_t pkt,
 static int sock_mmsg_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 			  odp_packet_t pkt_table[], int len)
 {
-	pktio_ops_socket_data_t *pkt_sock =
-		odp_ops_data(pktio_entry, socket);
+	pktio_ops_socket_data_t *pkt_sock = pktio_entry->s.ops_data;
 	odp_pool_t pool = pkt_sock->pool;
 	odp_time_t ts_val;
 	odp_time_t *ts = NULL;
@@ -375,8 +385,7 @@ static uint32_t _tx_pkt_to_iovec(odp_packet_t pkt,
 static int sock_mmsg_send(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 			  const odp_packet_t pkt_table[], int len)
 {
-	pktio_ops_socket_data_t *pkt_sock =
-		odp_ops_data(pktio_entry, socket);
+	pktio_ops_socket_data_t *pkt_sock = pktio_entry->s.ops_data;
 	struct mmsghdr msgvec[len];
 	struct iovec iovecs[len][MAX_SEGS];
 	int ret;
@@ -422,8 +431,7 @@ static int sock_mmsg_send(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
  */
 static uint32_t sock_mtu_get(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_socket_data_t *pkt_sock =
-		odp_ops_data(pktio_entry, socket);
+	pktio_ops_socket_data_t *pkt_sock = pktio_entry->s.ops_data;
 
 	return pkt_sock->mtu;
 }
@@ -434,8 +442,7 @@ static uint32_t sock_mtu_get(pktio_entry_t *pktio_entry)
 static int sock_mac_addr_get(pktio_entry_t *pktio_entry,
 			     void *mac_addr)
 {
-	pktio_ops_socket_data_t *pkt_sock =
-		odp_ops_data(pktio_entry, socket);
+	pktio_ops_socket_data_t *pkt_sock = pktio_entry->s.ops_data;
 
 	memcpy(mac_addr, pkt_sock->if_mac, ETH_ALEN);
 	return ETH_ALEN;
@@ -447,8 +454,7 @@ static int sock_mac_addr_get(pktio_entry_t *pktio_entry,
 static int sock_promisc_mode_set(pktio_entry_t *pktio_entry,
 				 odp_bool_t enable)
 {
-	pktio_ops_socket_data_t *pkt_sock =
-		odp_ops_data(pktio_entry, socket);
+	pktio_ops_socket_data_t *pkt_sock = pktio_entry->s.ops_data;
 
 	return promisc_mode_set_fd(pkt_sock->sockfd,
 				   pktio_entry->s.name, enable);
@@ -459,8 +465,7 @@ static int sock_promisc_mode_set(pktio_entry_t *pktio_entry,
  */
 static int sock_promisc_mode_get(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_socket_data_t *pkt_sock =
-		odp_ops_data(pktio_entry, socket);
+	pktio_ops_socket_data_t *pkt_sock = pktio_entry->s.ops_data;
 
 	return promisc_mode_get_fd(pkt_sock->sockfd,
 				   pktio_entry->s.name);
@@ -468,8 +473,7 @@ static int sock_promisc_mode_get(pktio_entry_t *pktio_entry)
 
 static int sock_link_status(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_socket_data_t *pkt_sock =
-		odp_ops_data(pktio_entry, socket);
+	pktio_ops_socket_data_t *pkt_sock = pktio_entry->s.ops_data;
 
 	return link_status_fd(pkt_sock->sockfd,
 			      pktio_entry->s.name);
@@ -493,8 +497,7 @@ static int sock_capability(pktio_entry_t *pktio_entry ODP_UNUSED,
 static int sock_stats(pktio_entry_t *pktio_entry,
 		      odp_pktio_stats_t *stats)
 {
-	pktio_ops_socket_data_t *pkt_sock =
-		odp_ops_data(pktio_entry, socket);
+	pktio_ops_socket_data_t *pkt_sock = pktio_entry->s.ops_data;
 
 	if (pktio_entry->s.stats_type == STATS_UNSUPPORTED) {
 		memset(stats, 0, sizeof(*stats));
@@ -506,8 +509,7 @@ static int sock_stats(pktio_entry_t *pktio_entry,
 
 static int sock_stats_reset(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_socket_data_t *pkt_sock =
-		odp_ops_data(pktio_entry, socket);
+	pktio_ops_socket_data_t *pkt_sock = pktio_entry->s.ops_data;
 
 	if (pktio_entry->s.stats_type == STATS_UNSUPPORTED) {
 		memset(&pktio_entry->s.stats, 0,
diff --git a/platform/linux-generic/pktio/socket_mmap.c b/platform/linux-generic/pktio/socket_mmap.c
index b5c27ef4b..271c2f0f7 100644
--- a/platform/linux-generic/pktio/socket_mmap.c
+++ b/platform/linux-generic/pktio/socket_mmap.c
@@ -494,23 +494,27 @@ static int mmap_bind_sock(pktio_ops_socket_mmap_data_t *pkt_sock,
 
 static int sock_mmap_close(pktio_entry_t *entry)
 {
-	pktio_ops_socket_mmap_data_t
-		*const pkt_sock = odp_ops_data(entry, socket_mmap);
+	pktio_ops_socket_mmap_data_t *const pkt_sock = entry->s.ops_data;
 	int ret;
+	int status = 0;
 
 	ret = mmap_unmap_sock(pkt_sock);
 	if (ret != 0) {
 		ODP_ERR("mmap_unmap_sock() %s\n", strerror(errno));
-		return -1;
+		status = -1;
 	}
 
 	if (pkt_sock->sockfd != -1 && close(pkt_sock->sockfd) != 0) {
 		__odp_errno = errno;
 		ODP_ERR("close(sockfd): %s\n", strerror(errno));
-		return -1;
+		status = -1;
 	}
 
-	return 0;
+	if (ODP_OPS_DATA_FREE(entry->s.ops_data)) {
+		ODP_ERR("ops_data_free(sock_mmap) failed\n");
+		status = -1;
+	}
+	return status;
 }
 
 static int sock_mmap_open(odp_pktio_t id ODP_UNUSED,
@@ -520,22 +524,27 @@ static int sock_mmap_open(odp_pktio_t id ODP_UNUSED,
 	int if_idx;
 	int ret = 0;
 	odp_pktio_stats_t cur_stats;
+	pktio_ops_socket_mmap_data_t *pkt_sock;
+	int fanout = 1;
 
 	if (disable_pktio)
 		return -1;
 
-	pktio_ops_socket_mmap_data_t
-		*const pkt_sock = odp_ops_data(pktio_entry, socket_mmap);
-	int fanout = 1;
+	if (pool == ODP_POOL_INVALID)
+		return -1;
+
+	pktio_entry->s.ops_data = ODP_OPS_DATA_ALLOC(sizeof(*pkt_sock));
+	if (odp_unlikely(pktio_entry->s.ops_data == NULL)) {
+		ODP_ERR("Failed to allocate pktio_ops_socket_mmap_data_t struct");
+		return -1;
+	}
+	pkt_sock = pktio_entry->s.ops_data;
 
 	/* Init pktio entry */
 	memset(pkt_sock, 0, sizeof(*pkt_sock));
 	/* set sockfd to -1, because a valid socked might be initialized to 0 */
 	pkt_sock->sockfd = -1;
 
-	if (pool == ODP_POOL_INVALID)
-		return -1;
-
 	/* Store eth buffer offset for pkt buffers from this pool */
 	pkt_sock->frame_offset = 0;
 
@@ -610,8 +619,7 @@ static int sock_mmap_open(odp_pktio_t id ODP_UNUSED,
 static int sock_mmap_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 			  odp_packet_t pkt_table[], int len)
 {
-	pktio_ops_socket_mmap_data_t
-		*const pkt_sock = odp_ops_data(pktio_entry, socket_mmap);
+	pktio_ops_socket_mmap_data_t *const pkt_sock = pktio_entry->s.ops_data;
 	int ret;
 
 	odp_ticketlock_lock(&pktio_entry->s.rxl);
@@ -626,8 +634,7 @@ static int sock_mmap_send(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 			  const odp_packet_t pkt_table[], int len)
 {
 	int ret;
-	pktio_ops_socket_mmap_data_t
-		*const pkt_sock = odp_ops_data(pktio_entry, socket_mmap);
+	pktio_ops_socket_mmap_data_t *const pkt_sock = pktio_entry->s.ops_data;
 
 	odp_ticketlock_lock(&pktio_entry->s.txl);
 	ret = pkt_mmap_v2_tx(pkt_sock->tx_ring.sock, &pkt_sock->tx_ring,
@@ -639,16 +646,14 @@ static int sock_mmap_send(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 
 static uint32_t sock_mmap_mtu_get(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_socket_mmap_data_t
-		*const pkt_sock = odp_ops_data(pktio_entry, socket_mmap);
+	pktio_ops_socket_mmap_data_t *const pkt_sock = pktio_entry->s.ops_data;
 
 	return mtu_get_fd(pkt_sock->sockfd, pktio_entry->s.name);
 }
 
 static int sock_mmap_mac_addr_get(pktio_entry_t *pktio_entry, void *mac_addr)
 {
-	pktio_ops_socket_mmap_data_t
-		*const pkt_sock = odp_ops_data(pktio_entry, socket_mmap);
+	pktio_ops_socket_mmap_data_t *const pkt_sock = pktio_entry->s.ops_data;
 
 	memcpy(mac_addr, pkt_sock->if_mac, ETH_ALEN);
 	return ETH_ALEN;
@@ -657,8 +662,7 @@ static int sock_mmap_mac_addr_get(pktio_entry_t *pktio_entry, void *mac_addr)
 static int sock_mmap_promisc_mode_set(pktio_entry_t *pktio_entry,
 				      odp_bool_t enable)
 {
-	pktio_ops_socket_mmap_data_t
-		*const pkt_sock = odp_ops_data(pktio_entry, socket_mmap);
+	pktio_ops_socket_mmap_data_t *const pkt_sock = pktio_entry->s.ops_data;
 
 	return promisc_mode_set_fd(pkt_sock->sockfd,
 				   pktio_entry->s.name, enable);
@@ -666,8 +670,7 @@ static int sock_mmap_promisc_mode_set(pktio_entry_t *pktio_entry,
 
 static int sock_mmap_promisc_mode_get(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_socket_mmap_data_t
-		*const pkt_sock = odp_ops_data(pktio_entry, socket_mmap);
+	pktio_ops_socket_mmap_data_t *const pkt_sock = pktio_entry->s.ops_data;
 
 	return promisc_mode_get_fd(pkt_sock->sockfd,
 				   pktio_entry->s.name);
@@ -675,8 +678,7 @@ static int sock_mmap_promisc_mode_get(pktio_entry_t *pktio_entry)
 
 static int sock_mmap_link_status(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_socket_mmap_data_t
-		*const pkt_sock = odp_ops_data(pktio_entry, socket_mmap);
+	pktio_ops_socket_mmap_data_t *const pkt_sock = pktio_entry->s.ops_data;
 
 	return link_status_fd(pkt_sock->sockfd, pktio_entry->s.name);
 }
@@ -699,8 +701,7 @@ static int sock_mmap_capability(pktio_entry_t *pktio_entry ODP_UNUSED,
 static int sock_mmap_stats(pktio_entry_t *pktio_entry,
 			   odp_pktio_stats_t *stats)
 {
-	pktio_ops_socket_mmap_data_t
-		*const pkt_sock = odp_ops_data(pktio_entry, socket_mmap);
+	pktio_ops_socket_mmap_data_t *const pkt_sock = pktio_entry->s.ops_data;
 
 	if (pktio_entry->s.stats_type == STATS_UNSUPPORTED) {
 		memset(stats, 0, sizeof(*stats));
@@ -713,8 +714,7 @@ static int sock_mmap_stats(pktio_entry_t *pktio_entry,
 
 static int sock_mmap_stats_reset(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_socket_mmap_data_t
-		*const pkt_sock = odp_ops_data(pktio_entry, socket_mmap);
+	pktio_ops_socket_mmap_data_t *const pkt_sock = pktio_entry->s.ops_data;
 
 	if (pktio_entry->s.stats_type == STATS_UNSUPPORTED) {
 		memset(&pktio_entry->s.stats, 0,
diff --git a/platform/linux-generic/pktio/tap.c b/platform/linux-generic/pktio/tap.c
index 5bc7481d8..bb404d914 100644
--- a/platform/linux-generic/pktio/tap.c
+++ b/platform/linux-generic/pktio/tap.c
@@ -92,23 +92,31 @@ static int tap_pktio_open(odp_pktio_t id ODP_UNUSED,
 	int fd, skfd, flags;
 	uint32_t mtu;
 	struct ifreq ifr;
-	pktio_ops_tap_data_t *tap = odp_ops_data(pktio_entry, tap);
+	pktio_ops_tap_data_t *tap = NULL;
 
 	if (strncmp(devname, "tap:", 4) != 0)
 		return -1;
 
+	if (pool == ODP_POOL_INVALID)
+		return -1;
+
+	pktio_entry->s.ops_data = ODP_OPS_DATA_ALLOC(sizeof(*tap));
+	if (odp_unlikely(pktio_entry->s.ops_data == NULL)) {
+		ODP_ERR("Failed to allocate pktio_ops_tap_data_t struct");
+		return -1;
+	}
+	tap = pktio_entry->s.ops_data;
+
 	/* Init pktio entry */
 	memset(tap, 0, sizeof(*tap));
 	tap->fd = -1;
 	tap->skfd = -1;
 
-	if (pool == ODP_POOL_INVALID)
-		return -1;
-
 	fd = open("/dev/net/tun", O_RDWR);
 	if (fd < 0) {
 		__odp_errno = errno;
 		ODP_ERR("failed to open /dev/net/tun: %s\n", strerror(errno));
+		ODP_OPS_DATA_FREE(pktio_entry->s.ops_data);
 		return -1;
 	}
 
@@ -170,13 +178,14 @@ static int tap_pktio_open(odp_pktio_t id ODP_UNUSED,
 tap_err:
 	close(fd);
 	ODP_ERR("Tap device alloc failed.\n");
+	ODP_OPS_DATA_FREE(pktio_entry->s.ops_data);
 	return -1;
 }
 
 static int tap_pktio_start(pktio_entry_t *pktio_entry)
 {
 	struct ifreq ifr;
-	pktio_ops_tap_data_t *tap = odp_ops_data(pktio_entry, tap);
+	pktio_ops_tap_data_t *tap = pktio_entry->s.ops_data;
 
 	odp_memset(&ifr, 0, sizeof(ifr));
 	snprintf(ifr.ifr_name, IF_NAMESIZE, "%s",
@@ -207,7 +216,7 @@ static int tap_pktio_start(pktio_entry_t *pktio_entry)
 static int tap_pktio_stop(pktio_entry_t *pktio_entry)
 {
 	struct ifreq ifr;
-	pktio_ops_tap_data_t *tap = odp_ops_data(pktio_entry, tap);
+	pktio_ops_tap_data_t *tap = pktio_entry->s.ops_data;
 
 	odp_memset(&ifr, 0, sizeof(ifr));
 	snprintf(ifr.ifr_name, IF_NAMESIZE, "%s",
@@ -238,7 +247,7 @@ static int tap_pktio_stop(pktio_entry_t *pktio_entry)
 static int tap_pktio_close(pktio_entry_t *pktio_entry)
 {
 	int ret = 0;
-	pktio_ops_tap_data_t *tap = odp_ops_data(pktio_entry, tap);
+	pktio_ops_tap_data_t *tap = pktio_entry->s.ops_data;
 
 	if (tap->fd != -1 && close(tap->fd) != 0) {
 		__odp_errno = errno;
@@ -252,13 +261,18 @@ static int tap_pktio_close(pktio_entry_t *pktio_entry)
 		ret = -1;
 	}
 
+	if (ODP_OPS_DATA_FREE(pktio_entry->s.ops_data)) {
+		ODP_ERR("ops_data_free(tap) failed\n");
+		ret = -1;
+	}
+
 	return ret;
 }
 
 static odp_packet_t pack_odp_pkt(pktio_entry_t *pktio_entry, const void *data,
 				 unsigned int len, odp_time_t *ts)
 {
-	pktio_ops_tap_data_t *tap = odp_ops_data(pktio_entry, tap);
+	pktio_ops_tap_data_t *tap = pktio_entry->s.ops_data;
 	odp_packet_t pkt;
 	odp_packet_hdr_t *pkt_hdr;
 	odp_packet_hdr_t parsed_hdr;
@@ -302,7 +316,7 @@ static int tap_pktio_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 	ssize_t retval;
 	int i;
 	uint8_t buf[BUF_SIZE];
-	pktio_ops_tap_data_t *tap = odp_ops_data(pktio_entry, tap);
+	pktio_ops_tap_data_t *tap = pktio_entry->s.ops_data;
 	odp_time_t ts_val;
 	odp_time_t *ts = NULL;
 
@@ -342,7 +356,7 @@ static int tap_pktio_send_lockless(pktio_entry_t *pktio_entry,
 	int i, n;
 	uint32_t pkt_len;
 	uint8_t buf[BUF_SIZE];
-	pktio_ops_tap_data_t *tap = odp_ops_data(pktio_entry, tap);
+	pktio_ops_tap_data_t *tap = pktio_entry->s.ops_data;
 
 	for (i = 0; i < len; i++) {
 		pkt_len = odp_packet_len(pkts[i]);
@@ -404,7 +418,7 @@ static int tap_pktio_send(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 static uint32_t tap_mtu_get(pktio_entry_t *pktio_entry)
 {
 	uint32_t ret;
-	pktio_ops_tap_data_t *tap = odp_ops_data(pktio_entry, tap);
+	pktio_ops_tap_data_t *tap = pktio_entry->s.ops_data;
 
 	ret =  mtu_get_fd(tap->skfd, pktio_entry->s.name + 4);
 	if (ret > 0)
@@ -416,7 +430,7 @@ static uint32_t tap_mtu_get(pktio_entry_t *pktio_entry)
 static int tap_promisc_mode_set(pktio_entry_t *pktio_entry,
 				odp_bool_t enable)
 {
-	pktio_ops_tap_data_t *tap = odp_ops_data(pktio_entry, tap);
+	pktio_ops_tap_data_t *tap = pktio_entry->s.ops_data;
 
 	return promisc_mode_set_fd(tap->skfd,
 				   pktio_entry->s.name + 4, enable);
@@ -424,14 +438,14 @@ static int tap_promisc_mode_set(pktio_entry_t *pktio_entry,
 
 static int tap_promisc_mode_get(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_tap_data_t *tap = odp_ops_data(pktio_entry, tap);
+	pktio_ops_tap_data_t *tap = pktio_entry->s.ops_data;
 
 	return promisc_mode_get_fd(tap->skfd, pktio_entry->s.name + 4);
 }
 
 static int tap_mac_addr_get(pktio_entry_t *pktio_entry, void *mac_addr)
 {
-	pktio_ops_tap_data_t *tap = odp_ops_data(pktio_entry, tap);
+	pktio_ops_tap_data_t *tap = pktio_entry->s.ops_data;
 
 	memcpy(mac_addr, tap->if_mac, ETH_ALEN);
 	return ETH_ALEN;
@@ -439,7 +453,7 @@ static int tap_mac_addr_get(pktio_entry_t *pktio_entry, void *mac_addr)
 
 static int tap_mac_addr_set(pktio_entry_t *pktio_entry, const void *mac_addr)
 {
-	pktio_ops_tap_data_t *tap = odp_ops_data(pktio_entry, tap);
+	pktio_ops_tap_data_t *tap = pktio_entry->s.ops_data;
 
 	memcpy(tap->if_mac, mac_addr, ETH_ALEN);
 
@@ -449,7 +463,7 @@ static int tap_mac_addr_set(pktio_entry_t *pktio_entry, const void *mac_addr)
 
 static int tap_link_status(pktio_entry_t *pktio_entry)
 {
-	pktio_ops_tap_data_t *tap = odp_ops_data(pktio_entry, tap);
+	pktio_ops_tap_data_t *tap = pktio_entry->s.ops_data;
 
 	return link_status_fd(tap->skfd, pktio_entry->s.name + 4);
 }
