From b961dd5be361d930f00ea0d74fe5a596366096e7 Mon Sep 17 00:00:00 2001 From: Naveen N Date: Sat, 14 May 2016 14:44:23 +0530 Subject: [PATCH] * Remove flow mgmt tree lookup in DB context VRF delete notification happens in DB context, DB and flow mgmt runs in parallel. When VRF is deleted flow mgmt tree was lookup to check if there are any pending flows, since DB and flow mgmt run in parallel entries can be getting deleted resulting deleted memory access. Remove flow mgmt tree access, just enqueue a request to delete VRF, which inturn verifies if all the flows are deleted or not. Closes-bug:#1580733 Change-Id: I976185e0a7a77d9713b284abfdebe70c8b1579bd --- src/vnsw/agent/pkt/flow_mgmt.cc | 7 ++-- src/vnsw/agent/pkt/flow_mgmt.h | 1 + .../agent/pkt/test/test_flow_mgmt_route.cc | 35 +++++++++++++++++++ 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/vnsw/agent/pkt/flow_mgmt.cc b/src/vnsw/agent/pkt/flow_mgmt.cc index e2adb187473..0fa6d82f282 100644 --- a/src/vnsw/agent/pkt/flow_mgmt.cc +++ b/src/vnsw/agent/pkt/flow_mgmt.cc @@ -208,6 +208,9 @@ size_t FlowMgmtManager::FlowUpdateQueueLength() { return request_queue_.Length(); } +size_t FlowMgmtManager::FlowDBQueueLength() { + return db_event_queue_.Length(); +} ///////////////////////////////////////////////////////////////////////////// // Handlers for events from the work-queue ///////////////////////////////////////////////////////////////////////////// @@ -1612,7 +1615,5 @@ VrfFlowMgmtEntry::Data::~Data() { void VrfFlowMgmtEntry::Data::ManagedDelete() { deleted_ = true; - if (vrf_mgmt_entry_->CanDelete()) { - vrf_mgmt_entry_->vrf_tree()->mgr()->RetryVrfDeleteEvent(vrf_); - } + vrf_mgmt_entry_->vrf_tree()->mgr()->RetryVrfDeleteEvent(vrf_); } diff --git a/src/vnsw/agent/pkt/flow_mgmt.h b/src/vnsw/agent/pkt/flow_mgmt.h index 3c48f9d739f..e24f488e191 100644 --- a/src/vnsw/agent/pkt/flow_mgmt.h +++ b/src/vnsw/agent/pkt/flow_mgmt.h @@ -1060,6 +1060,7 @@ class FlowMgmtManager { void FlowUpdateQueueDisable(bool val); size_t FlowUpdateQueueLength(); + size_t FlowDBQueueLength(); private: // Handle Add/Change of a flow. Builds FlowMgmtKeyTree for all objects void AddFlow(FlowEntryPtr &flow); diff --git a/src/vnsw/agent/pkt/test/test_flow_mgmt_route.cc b/src/vnsw/agent/pkt/test/test_flow_mgmt_route.cc index a03d96ee585..204163e6729 100644 --- a/src/vnsw/agent/pkt/test/test_flow_mgmt_route.cc +++ b/src/vnsw/agent/pkt/test/test_flow_mgmt_route.cc @@ -313,6 +313,41 @@ TEST_F(FlowMgmtRouteTest, RouteDelete_5) { client->WaitForIdle(); } +TEST_F(FlowMgmtRouteTest, RouteAddDelete_6) { + VrfAddReq("vrf10"); + client->WaitForIdle(); + + boost::system::error_code ec; + Ip4Address remote_compute = Ip4Address::from_string("1.1.1.1", ec); + char router_id[80]; + strcpy(router_id, Agent::GetInstance()->router_id().to_string().c_str()); + + //uint32_t id = VrfGet("vrf10")->vrf_id(); + string vn_name = "vn10"; + for (uint32_t i = 1; i < 100; i++) { + Ip4Address ip(i); + Inet4TunnelRouteAdd(agent_->local_peer(), "vrf10", + ip, 32, + remote_compute, TunnelType::AllType(), 10, + vn_name, SecurityGroupList(), + PathPreference()); + client->WaitForIdle(); + } + + flow_mgmt_->FlowUpdateQueueDisable(true); + for (uint32_t i = 0; i < 100; i++) { + Ip4Address ip(i); + DeleteRoute("vrf10", ip.to_string().c_str(), 32, agent_->local_peer()); + client->WaitForIdle(); + } + + // Enable flow-mgmt queue + flow_mgmt_->FlowUpdateQueueDisable(false); + Agent::GetInstance()->vrf_table()->DeleteVrfReq("vrf10"); + WAIT_FOR(1000, 1000, (flow_mgmt_->FlowUpdateQueueLength() == 0)); + WAIT_FOR(1000, 10000, (VrfFind("vrf10", true) == false)); +} + //////////////////////////////////////////////////////////////////////////// // UT for bug 1551577 // Simulate the following scenario,