@@ -1580,8 +1580,8 @@ dp_netdev_pmd_remove_flow(struct dp_netdev_pmd_thread *pmd,
{
struct cmap_node *node = CONST_CAST(struct cmap_node *, &flow->node);
struct dpcls *cls;
- odp_port_t in_port = flow->flow.in_port.odp_port;
+ odp_port_t in_port = flow->flow.in_port.odp_port;
cls = dp_netdev_pmd_lookup_dpcls(pmd, in_port);
ovs_assert(cls != NULL);
if (pmd->dp->ppl_md.id == HW_OFFLOAD_PIPELINE &&
@@ -1589,8 +1589,7 @@ dp_netdev_pmd_remove_flow(struct dp_netdev_pmd_thread *pmd,
VLOG_INFO("hw_pipeline_dpcls_remove");
hw_pipeline_dpcls_remove(pmd->dp,&flow->cr);
}
- else
- {
+ else {
VLOG_INFO("skip hw_pipeline_dpcls_remove");
}
dpcls_remove(cls, &flow->cr);
@@ -4397,8 +4396,11 @@ static inline size_t
emc_processing(struct dp_netdev_pmd_thread *pmd,
struct dp_packet_batch *packets_,
struct netdev_flow_key *keys,
- struct packet_batch_per_flow batches[], size_t *n_batches,
- bool md_is_valid, odp_port_t port_no)
+ struct packet_batch_per_flow batches[],
+ size_t *n_batches,
+ bool md_is_valid,
+ odp_port_t port_no,
+ struct pipeline_md *md_tags)
{
struct emc_cache *flow_cache = &pmd->flow_cache;
struct netdev_flow_key *key = &keys[0];
@@ -4413,6 +4415,13 @@ emc_processing(struct dp_netdev_pmd_thread *pmd,
DP_PACKET_BATCH_REFILL_FOR_EACH (i, size, packet, packets_) {
struct dp_netdev_flow *flow;
+ if (md_tags[i].id == HW_OFFLOAD_PIPELINE &&
+ md_tags[i].flow_tag != HW_NO_FREE_FLOW_TAG) {
+ VLOG_INFO("skip emc_processing flow_tag %x\n ",
+ md_tags[i].flow_tag);
+ continue;
+ }
+
if (OVS_UNLIKELY(dp_packet_size(packet) < ETH_HEADER_LEN)) {
dp_packet_delete(packet);
n_dropped++;
@@ -4530,7 +4539,7 @@ fast_path_processing(struct dp_netdev_pmd_thread *pmd,
struct netdev_flow_key *keys,
struct packet_batch_per_flow batches[], size_t *n_batches,
odp_port_t in_port,
- long long now)
+ long long now,struct pipeline_md *md_tags)
{
int cnt = packets_->count;
#if !defined(__CHECKER__) && !defined(_WIN32)
@@ -4555,7 +4564,14 @@ fast_path_processing(struct dp_netdev_pmd_thread *pmd,
/* Get the classifier for the in_port */
cls = dp_netdev_pmd_lookup_dpcls(pmd, in_port);
if (OVS_LIKELY(cls)) {
- any_miss = !dpcls_lookup(cls, keys, rules, cnt, &lookup_cnt);
+ if (pmd->dp->ppl_md.id == DEFAULT_SW_PIPELINE) {
+ any_miss = !dpcls_lookup(cls, keys, rules, cnt, &lookup_cnt);
+ }
+ else {
+ memset(rules, 0, sizeof(rules));
+ any_miss = !hw_pipeline_dpcls_lookup(pmd->dp,md_tags,cnt,
+ &lookup_cnt);
+ }
} else {
any_miss = true;
memset(rules, 0, sizeof(rules));
@@ -4577,8 +4593,18 @@ fast_path_processing(struct dp_netdev_pmd_thread *pmd,
/* It's possible that an earlier slow path execution installed
* a rule covering this flow. In this case, it's a lot cheaper
* to catch it here than execute a miss. */
- netdev_flow = dp_netdev_pmd_lookup_flow(pmd, &keys[i],
- &add_lookup_cnt);
+
+ if (pmd->dp->ppl_md.id == DEFAULT_SW_PIPELINE) {
+ VLOG_INFO("dp_netdev_pmd_lookup_flow \n");
+ netdev_flow = dp_netdev_pmd_lookup_flow(pmd,&keys[i],
+ &add_lookup_cnt);
+ }
+ else {
+ VLOG_INFO("hw_pipeline_lookup_flow \n");
+ netdev_flow = hw_pipeline_lookup_flow(pmd->dp,
+ md_tags[i].flow_tag,&add_lookup_cnt);
+ }
+
if (netdev_flow) {
lookup_cnt += add_lookup_cnt;
rules[i] = &netdev_flow->cr;
@@ -4645,18 +4671,26 @@ dp_netdev_input__(struct dp_netdev_pmd_thread *pmd,
OVS_ALIGNED_VAR(CACHE_LINE_SIZE)
struct netdev_flow_key keys[PKT_ARRAY_SIZE];
struct packet_batch_per_flow batches[PKT_ARRAY_SIZE];
+ struct pipeline_md md_tags[PKT_ARRAY_SIZE];
long long now = time_msec();
size_t n_batches;
odp_port_t in_port;
+ int index=0;
n_batches = 0;
+
+ for (index=0;index<cnt;index++) {
+ md_tags[index].id = DEFAULT_SW_PIPELINE;
+ md_tags[index].flow_tag = HW_NO_FREE_FLOW_TAG;
+ }
+
emc_processing(pmd, packets, keys, batches, &n_batches,
- md_is_valid, port_no);
+ md_is_valid, port_no,md_tags);
if (!dp_packet_batch_is_empty(packets)) {
/* Get ingress port from first packet's metadata. */
in_port = packets->packets[0]->md.in_port.odp_port;
- fast_path_processing(pmd, packets, keys, batches, &n_batches,
- in_port, now);
+ fast_path_processing(pmd, packets, keys, batches, &n_batches, in_port,
+ now,md_tags);
}
/* All the flow batches need to be reset before any call to
@@ -36,6 +36,8 @@
VLOG_DEFINE_THIS_MODULE(hw_pipeline);
+static struct dp_netdev_flow *hw_pipeline_read_flow(flow_tag_pool *p,
+ uint32_t flow_tag);
static int hw_pipeline_send_insert_flow(struct dp_netdev *dp,
odp_port_t in_port,
struct dp_netdev_flow *flow,
@@ -53,6 +55,10 @@ bool hw_pipeline_ft_pool_is_valid(flow_tag_pool *p);
uint32_t hw_pipeline_ft_pool_init(flow_tag_pool *p,uint32_t pool_size);
uint32_t hw_pipeline_ft_pool_uninit(flow_tag_pool *p);
+
+struct dp_netdev_flow *hw_pipeline_ft_pool_read_flow(flow_tag_pool *p,
+ uint32_t handle);
+
// Internal functions Message Queue
static int hw_pipeline_msg_queue_init(msg_queue *message_queue,
@@ -87,6 +93,50 @@ bool hw_pipeline_ft_pool_is_valid(flow_tag_pool *p)
return false;
}
+flow_elem *hw_pipeline_ft_pool_read_elem(struct dp_netdev *dp,
+ uint32_t handle)
+{
+ uint32_t index;
+ flow_elem *elem;
+
+ if (OVS_UNLIKELY(dp == NULL)) {
+ VLOG_ERR("no dp pointer \n");
+ return NULL;
+ }
+
+ index = OVS_FLOW_TAG_INDEX_GET(handle);
+ if (OVS_UNLIKELY(index >= HW_MAX_FLOW_TAG)) {
+ VLOG_ERR("index out of range\n");
+ return NULL;
+ }
+
+ rte_spinlock_lock(&dp->ft_pool.lock);
+ elem = &dp->ft_pool.ft_data[index];
+ rte_spinlock_unlock(&dp->ft_pool.lock);
+
+ return elem;
+}
+
+
+inline struct dp_netdev_flow *hw_pipeline_ft_pool_read_flow(flow_tag_pool *p,
+ uint32_t handle)
+{
+ uint32_t index;
+ struct dp_netdev_flow *flow=NULL;
+ index = OVS_FLOW_TAG_INDEX_GET(handle);
+ if (OVS_UNLIKELY(index >= HW_MAX_FLOW_TAG)) {
+ VLOG_ERR("index out of range\n");
+ return NULL;
+ }
+
+ rte_spinlock_lock(&p->lock);
+ p->ft_data[index].valid =true;
+ flow = p->ft_data[index].sw_flow;
+ rte_spinlock_unlock(&p->lock);
+
+ return flow;
+}
+
uint32_t hw_pipeline_ft_pool_init(flow_tag_pool *p,
uint32_t pool_size)
{
@@ -343,10 +393,23 @@ static bool hw_pipeline_msg_queue_enqueue(msg_queue *message_queue,
}
return false;
}
-
return true;
}
+static struct dp_netdev_flow *hw_pipeline_read_flow(flow_tag_pool *p,
+ uint32_t handle)
+{
+ struct dp_netdev_flow *netdev_flow=NULL;
+ netdev_flow = hw_pipeline_ft_pool_read_flow(p,handle);
+ if (OVS_UNLIKELY(netdev_flow == NULL)) {
+ VLOG_INFO("No flow found");
+ return NULL;
+ }
+ VLOG_INFO("flow found with tag %x\n",netdev_flow->cr.flow_tag);
+ VLOG_INFO("flow found with handle %x\n",handle);
+ return netdev_flow;
+}
+
static int hw_pipeline_send_insert_flow(struct dp_netdev *dp,
odp_port_t in_port, struct dp_netdev_flow *flow, struct flow *masks,
int rxqid)
@@ -438,6 +501,34 @@ static int hw_pipeline_send_remove_flow(struct dp_netdev *dp,uint32_t flow_tag,
return 0;
}
+bool hw_pipeline_dpcls_lookup(struct dp_netdev *dp,
+ struct pipeline_md *md_tags,
+ const size_t cnt,
+ int *lookup_cnt)
+{
+ int index =0 ;
+ struct dp_netdev_flow *netdev_flow = NULL;
+ bool all_found = true;
+ bool never_lookup = true;
+
+ for (index=0;index<cnt;index++) {
+ if (md_tags[index].flow_tag == HW_NO_FREE_FLOW_TAG) {
+ continue;
+ }
+ never_lookup = false;
+ netdev_flow = hw_pipeline_lookup_flow(dp,
+ md_tags[index].flow_tag,lookup_cnt);
+ if (netdev_flow == NULL) {
+ VLOG_INFO("flow== NULL && miss_any=true");
+ all_found=false;
+ }
+ }
+ if (never_lookup) {
+ return false;
+ }
+ return all_found;
+}
+
/* Insert 'rule' into 'cls'.
* Get a unique tag from pool
* The function sends a message to the message queue
@@ -491,3 +582,25 @@ hw_pipeline_dpcls_remove(struct dp_netdev *dp,
}
}
}
+
+struct dp_netdev_flow *
+hw_pipeline_lookup_flow(struct dp_netdev *dp,
+ uint32_t flow_tag,
+ int *lookup_cnt)
+{
+ struct dp_netdev_flow *netdev_flow=NULL;
+ if (OVS_UNLIKELY(flow_tag == HW_NO_FREE_FLOW_TAG)) {
+ return NULL;
+ }
+ netdev_flow = hw_pipeline_read_flow(&dp->ft_pool,flow_tag);
+ if (netdev_flow != NULL) {
+ if (lookup_cnt != NULL) {
+ *lookup_cnt=+1;
+ }
+ }
+ else {
+ VLOG_ERR("No flow found : netdev_flow %p for flow_tag %x",
+ netdev_flow,flow_tag);
+ }
+ return netdev_flow;
+}
PMD fetch the flow according to the flow tag . Signed-off-by: Shachar Beiser <shacharbe@mellanox.com> Conflicts: lib/dpif-netdev.c lib/hw-pipeline.c --- lib/dpif-netdev.c | 58 +++++++++++++++++++++------ lib/hw-pipeline.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 160 insertions(+), 13 deletions(-)