From eb56698b27d5b3da2a395b4e5f1a50c5042ac7ba Mon Sep 17 00:00:00 2001 From: Naveen N Date: Fri, 26 Aug 2016 12:06:42 +0530 Subject: [PATCH] * Add queue is field in qos-queue config Mapping from id in qos-queue config to hardware queue will be specified in agent.conf, example queue config will look as below [QUEUE] NIC-QUEUE-1 = [1, 2 , 5] NIC-QUEUE-2 = [6 - 10, 11 - 15] default_nic_queue = 1 Default nic queue will be used if no options is specified Partial-bug:#1571493 Change-Id: Ibbf2d1b53012a9814248967fa84679d210d9f53f --- src/schema/vnc_cfg.xsd | 4 ++ src/vnsw/agent/cmn/agent.h | 2 +- src/vnsw/agent/init/agent_param.cc | 51 ++++++++++++++++++- src/vnsw/agent/init/agent_param.h | 15 ++++++ src/vnsw/agent/init/test/cfg.ini | 6 ++- src/vnsw/agent/init/test/test_agent_init.cc | 4 ++ src/vnsw/agent/oper/agent.sandesh | 1 + src/vnsw/agent/oper/forwarding_class.cc | 6 +++ src/vnsw/agent/oper/forwarding_class.h | 5 ++ .../agent/oper/ifmap_dependency_manager.cc | 9 +++- src/vnsw/agent/oper/qos_queue.cc | 32 ++++++++---- src/vnsw/agent/oper/qos_queue.h | 15 ++++-- .../agent/oper/test/test_forwarding_class.cc | 26 ++++++++++ src/vnsw/agent/test/test_cmn_util.h | 1 + src/vnsw/agent/test/test_util.cc | 14 +++++ .../vrouter/ksync/forwarding_class_ksync.cc | 19 ++++--- .../vrouter/ksync/forwarding_class_ksync.h | 1 + 17 files changed, 186 insertions(+), 25 deletions(-) diff --git a/src/schema/vnc_cfg.xsd b/src/schema/vnc_cfg.xsd index b3400cc78bf..556ddca2293 100644 --- a/src/schema/vnc_cfg.xsd +++ b/src/schema/vnc_cfg.xsd @@ -1098,6 +1098,10 @@ targetNamespace="http://www.contrailsystems.com/2012/VNC-CONFIG/0"> + + diff --git a/src/vnsw/agent/cmn/agent.h b/src/vnsw/agent/cmn/agent.h index 03d95a58ce1..a7ee7cb34eb 100644 --- a/src/vnsw/agent/cmn/agent.h +++ b/src/vnsw/agent/cmn/agent.h @@ -292,7 +292,7 @@ class Agent { static const uint32_t kFlowKSyncTokens = 25; static const uint32_t kFlowDelTokens = 16; static const uint32_t kFlowUpdateTokens = 16; - + static const uint8_t kInvalidQueueId = 255; enum ForwardingMode { NONE, L2_L3, diff --git a/src/vnsw/agent/init/agent_param.cc b/src/vnsw/agent/init/agent_param.cc index af9cafc080c..4799f9216f7 100644 --- a/src/vnsw/agent/init/agent_param.cc +++ b/src/vnsw/agent/init/agent_param.cc @@ -677,6 +677,53 @@ void AgentParam::ParseServices() { GetValueFromTree(services_queue_limit_, "SERVICES.queue_limit"); } +void AgentParam::ParseQueue() { + GetValueFromTree(default_nic_queue_, "QUEUE.default_nic_queue"); + + if (!tree_.get_child_optional("QUEUE")) { + return; + } + + BOOST_FOREACH(ptree::value_type &v, tree_.get_child("QUEUE")) { + std::string nic_queue = v.first; + std::string input = v.second.get_value(); + std::vector tokens; + std::string sep = "[],"; + boost::split(tokens, input, boost::is_any_of(sep), + boost::token_compress_on); + + uint16_t queue; + if (sscanf(nic_queue.c_str(), "NIC-QUEUE-%hu", &queue) != 1) { + continue; + } + + for (std::vector::const_iterator it = tokens.begin(); + it != tokens.end(); it++) { + + if (*it == Agent::NullString()) { + continue; + } + + string range = *it; + std::vector range_value; + if (stringToIntegerList(range, "-", range_value)) { + if (range_value.size() == 1) { + qos_queue_map_[range_value[0]] = queue; + continue; + } + + if (range_value[0] > range_value[1]) { + continue; + } + + for (uint16_t i = range_value[0]; i <= range_value[1]; i++) { + qos_queue_map_[i] = queue; + } + } + } + } +} + void AgentParam::ParseCollectorDSArguments (const boost::program_options::variables_map &var_map) { GetOptValue< vector >(var_map, collector_server_list_, @@ -990,6 +1037,7 @@ void AgentParam::InitFromConfig() { ParseNexthopServer(); ParsePlatform(); ParseServices(); + ParseQueue(); cout << "Config file <" << config_file_ << "> parsing completed.\n"; return; } @@ -1427,7 +1475,8 @@ AgentParam::AgentParam(bool enable_flow_options, tbb_thread_count_(Agent::kMaxTbbThreads), tbb_exec_delay_(0), tbb_schedule_delay_(0), - tbb_keepawake_timeout_(Agent::kDefaultTbbKeepawakeTimeout) { + tbb_keepawake_timeout_(Agent::kDefaultTbbKeepawakeTimeout), + default_nic_queue_(Agent::kInvalidQueueId) { // Set common command line arguments supported boost::program_options::options_description generic("Generic options"); generic.add_options() diff --git a/src/vnsw/agent/init/agent_param.h b/src/vnsw/agent/init/agent_param.h index 56961e23648..b9522f5299f 100644 --- a/src/vnsw/agent/init/agent_param.h +++ b/src/vnsw/agent/init/agent_param.h @@ -289,6 +289,18 @@ class AgentParam { void set_pkt0_tx_buffer_count(uint32_t val) { pkt0_tx_buffer_count_ = val; } bool measure_queue_delay() const { return measure_queue_delay_; } void set_measure_queue_delay(bool val) { measure_queue_delay_ = val; } + uint16_t get_nic_queue(uint16_t queue) { + std::map::iterator it = qos_queue_map_.find(queue); + if (it != qos_queue_map_.end()) { + return it->second; + } + return default_nic_queue_; + } + + void add_nic_queue(uint16_t queue, uint16_t nic_queue) { + qos_queue_map_[queue] = nic_queue; + } + protected: void set_hypervisor_mode(HypervisorMode m) { hypervisor_mode_ = m; } virtual void InitFromSystem(); @@ -367,6 +379,7 @@ class AgentParam { void ParseNexthopServer(); void ParsePlatform(); void ParseServices(); + void ParseQueue(); void set_agent_mode(const std::string &mode); void set_gateway_mode(const std::string &mode); @@ -519,6 +532,8 @@ class AgentParam { uint32_t tbb_exec_delay_; uint32_t tbb_schedule_delay_; uint32_t tbb_keepawake_timeout_; + std::map qos_queue_map_; + uint16_t default_nic_queue_; DISALLOW_COPY_AND_ASSIGN(AgentParam); }; diff --git a/src/vnsw/agent/init/test/cfg.ini b/src/vnsw/agent/init/test/cfg.ini index 3f1a7062c1d..874e675fc8f 100644 --- a/src/vnsw/agent/init/test/cfg.ini +++ b/src/vnsw/agent/init/test/cfg.ini @@ -150,4 +150,8 @@ ip_blocks=1.1.1.1/24 # Routes to be exported in routing_instance. Each route is represented as # ip/prefix. Multiple routes are represented by separating each with a space # routes= 10.10.10.1/24 11.11.11.1/24 - +[QUEUE] +NIC-QUEUE-1=[1, 3, 5] +NIC-QUEUE-2=[6-10] +NIC-QUEUE-3=[110-109] +default_nic_queue = 8 diff --git a/src/vnsw/agent/init/test/test_agent_init.cc b/src/vnsw/agent/init/test/test_agent_init.cc index 4a9b97d59d3..36212e9a1f6 100644 --- a/src/vnsw/agent/init/test/test_agent_init.cc +++ b/src/vnsw/agent/init/test/test_agent_init.cc @@ -86,6 +86,10 @@ TEST_F(FlowTest, Agent_Conf_file_1) { EXPECT_TRUE(param.flow_trace_enable()); EXPECT_EQ(param.pkt0_tx_buffer_count(), 2000); EXPECT_EQ(param.pkt0_tx_buffer_count(), 2000); + EXPECT_EQ(param.get_nic_queue(1), 1); + EXPECT_EQ(param.get_nic_queue(3), 1); + EXPECT_EQ(param.get_nic_queue(8), 2); + EXPECT_EQ(param.get_nic_queue(105), 8); } TEST_F(FlowTest, Agent_Conf_file_2) { diff --git a/src/vnsw/agent/oper/agent.sandesh b/src/vnsw/agent/oper/agent.sandesh index 299c1eeacac..fd34676f2b4 100644 --- a/src/vnsw/agent/oper/agent.sandesh +++ b/src/vnsw/agent/oper/agent.sandesh @@ -2113,6 +2113,7 @@ response sandesh AgentQosConfigSandeshResp { request sandesh AddQosQueue { 1: u32 uuid; 2: string name; + 3: u16 id; } request sandesh DeleteQosQueue { diff --git a/src/vnsw/agent/oper/forwarding_class.cc b/src/vnsw/agent/oper/forwarding_class.cc index 62b361fc7bd..45aae5cf574 100644 --- a/src/vnsw/agent/oper/forwarding_class.cc +++ b/src/vnsw/agent/oper/forwarding_class.cc @@ -96,6 +96,12 @@ bool ForwardingClass::Change(const DBRequest *req) { ret = true; } + if (qos_queue_ref_.get()) { + if (nic_queue_id_ != qos_queue_ref_->nic_queue_id()) { + nic_queue_id_ = qos_queue_ref_->nic_queue_id(); + ret = true; + } + } return ret; } diff --git a/src/vnsw/agent/oper/forwarding_class.h b/src/vnsw/agent/oper/forwarding_class.h index 9f9468e8666..440f2508ffc 100644 --- a/src/vnsw/agent/oper/forwarding_class.h +++ b/src/vnsw/agent/oper/forwarding_class.h @@ -82,6 +82,10 @@ class ForwardingClass : return name_; } + uint16_t nic_queue_id() const { + return nic_queue_id_; + } + private: boost::uuids::uuid uuid_; uint32_t id_; @@ -90,6 +94,7 @@ class ForwardingClass : uint32_t mpls_exp_; QosQueueConstRef qos_queue_ref_; std::string name_; + uint16_t nic_queue_id_; DISALLOW_COPY_AND_ASSIGN(ForwardingClass); }; diff --git a/src/vnsw/agent/oper/ifmap_dependency_manager.cc b/src/vnsw/agent/oper/ifmap_dependency_manager.cc index 1e2cc1083f3..4d0baa00837 100644 --- a/src/vnsw/agent/oper/ifmap_dependency_manager.cc +++ b/src/vnsw/agent/oper/ifmap_dependency_manager.cc @@ -716,13 +716,18 @@ void IFMapDependencyManager::InitializeDependencyRules(Agent *agent) { RegisterConfigHandler(this, "service-health-check", agent ? agent->health_check_table() : NULL); - AddDependencyPath("qos-config", - MakePath("global-qos-config", + AddDependencyPath("qos-config", + MakePath("global-qos-config-qos-config", "qos-config", true)); RegisterConfigHandler(this, "qos-config", agent ? agent->qos_config_table() : NULL); + RegisterConfigHandler(this, "qos-queue", agent ? agent->qos_queue_table() : NULL); + + AddDependencyPath("forwarding-class", + MakePath("forwarding-class-qos-queue", + "qos-queue", true)); RegisterConfigHandler(this, "forwarding-class", agent ? agent->forwarding_class_table() : NULL); } diff --git a/src/vnsw/agent/oper/qos_queue.cc b/src/vnsw/agent/oper/qos_queue.cc index 0bb68675828..8160d186829 100644 --- a/src/vnsw/agent/oper/qos_queue.cc +++ b/src/vnsw/agent/oper/qos_queue.cc @@ -9,15 +9,13 @@ #include #include #include +#include QosQueue::QosQueue(const boost::uuids::uuid &uuid): uuid_(uuid), id_(QosQueueTable::kInvalidIndex) { } QosQueue::~QosQueue() { - if (id_ != QosQueueTable::kInvalidIndex) { - static_cast(get_table())->ReleaseIndex(this); - } } DBEntryBase::KeyPtr QosQueue::GetDBRequestKey() const { @@ -49,13 +47,30 @@ bool QosQueue::IsLess(const DBEntry &rhs) const { return (uuid_ < qos_q.uuid_); } +void QosQueue::PostAdd() { + AgentDBTable *table = static_cast(get_table()); + nic_queue_id_ = table->agent()->params()->get_nic_queue(id_); +} + bool QosQueue::Change(const DBRequest *req) { + const AgentDBTable *table = static_cast(get_table()); const QosQueueData *data = static_cast(req->data.get()); + bool ret = false; if (name_ != data->name_) { name_ = data->name_; + ret = true; } - return false; + + if (id_ != data->id_) { + id_ = data->id_; + if (table) { + nic_queue_id_ = table->agent()->params()->get_nic_queue(id_); + } + ret = true; + } + + return ret; } void QosQueue::Delete(const DBRequest *req) { @@ -142,17 +157,16 @@ bool QosQueueTable::ProcessConfig(IFMapNode *node, DBRequest &req, return false; } + autogen::QosQueue *cfg = static_cast (node->GetObject()); req.oper = DBRequest::DB_ENTRY_ADD_CHANGE; req.key.reset(new QosQueueKey(u)); - req.data.reset(new QosQueueData(agent(), node, node->name())); + req.data.reset(new QosQueueData(agent(), node, node->name(), + cfg->identifier())); Enqueue(&req); return false; } void QosQueueTable::ReleaseIndex(QosQueue *qos_q) { - if (qos_q->id() != kInvalidIndex) { - index_table_.Remove(qos_q->id()); - } } AgentSandeshPtr @@ -181,7 +195,7 @@ void AddQosQueue::HandleRequest() const { boost::uuids::uuid u1 = StringToUuid(std::string(str)); req.oper = DBRequest::DB_ENTRY_ADD_CHANGE; req.key.reset(new QosQueueKey(u1)); - req.data.reset(new QosQueueData(NULL, NULL, get_name())); + req.data.reset(new QosQueueData(NULL, NULL, get_name(), get_id())); table->Enqueue(&req); resp->Response(); } diff --git a/src/vnsw/agent/oper/qos_queue.h b/src/vnsw/agent/oper/qos_queue.h index 66e8771411b..d6d7ecfcd43 100644 --- a/src/vnsw/agent/oper/qos_queue.h +++ b/src/vnsw/agent/oper/qos_queue.h @@ -28,9 +28,11 @@ struct QosQueueKey : public AgentOperDBKey { struct QosQueueData : public AgentOperDBData { - QosQueueData(const Agent *agent, IFMapNode *node, const std::string &name): - AgentOperDBData(agent, node), name_(name) {} + QosQueueData(const Agent *agent, IFMapNode *node, const std::string &name, + uint16_t id): + AgentOperDBData(agent, node), name_(name), id_(id) {} std::string name_; + uint16_t id_; }; class QosQueue : @@ -47,6 +49,7 @@ class QosQueue : virtual bool Change(const DBRequest *req); virtual void Delete(const DBRequest *req); virtual void SetKey(const DBRequestKey *key); + virtual void PostAdd(); virtual bool DeleteOnZeroRefCount() const { return false; @@ -67,10 +70,16 @@ class QosQueue : const std::string& name() const { return name_; } + + uint16_t nic_queue_id() const { + return nic_queue_id_; + } + private: boost::uuids::uuid uuid_; - uint32_t id_; + uint16_t id_; std::string name_; + uint16_t nic_queue_id_; DISALLOW_COPY_AND_ASSIGN(QosQueue); }; diff --git a/src/vnsw/agent/oper/test/test_forwarding_class.cc b/src/vnsw/agent/oper/test/test_forwarding_class.cc index 982cbb6e7a3..463e8ad8732 100644 --- a/src/vnsw/agent/oper/test/test_forwarding_class.cc +++ b/src/vnsw/agent/oper/test/test_forwarding_class.cc @@ -111,6 +111,32 @@ TEST_F(FwdClassTest, Test3) { EXPECT_TRUE(agent->forwarding_class_table()->Size() == 0); } +TEST_F(FwdClassTest, Test4) { + TestForwardingClassData data[] = { + {1, 1, 1, 1, 1}, + }; + + Agent::GetInstance()->params()->add_nic_queue(10, 100); + + AddGlobalConfig(data, 1); + client->WaitForIdle(); + EXPECT_TRUE(agent->forwarding_class_table()->Size() == 1); + VerifyForwardingClass(agent, data, 1); + + ForwardingClassKey key(MakeUuid(data[0].id_)); + ForwardingClass *fc = static_cast( + agent->forwarding_class_table()->FindActiveEntry(&key)); + EXPECT_TRUE(fc->nic_queue_id() == Agent::kInvalidQueueId); + + AddQosQueue("qosqueue1", 1, 10); + client->WaitForIdle(); + + EXPECT_TRUE(fc->nic_queue_id() == 100); + + DelGlobalConfig(data, 1); + client->WaitForIdle(); + EXPECT_TRUE(agent->forwarding_class_table()->Size() == 0); +} int main(int argc, char **argv) { GETUSERARGS(); diff --git a/src/vnsw/agent/test/test_cmn_util.h b/src/vnsw/agent/test/test_cmn_util.h index 1c96c7108ff..c24beea1807 100644 --- a/src/vnsw/agent/test/test_cmn_util.h +++ b/src/vnsw/agent/test/test_cmn_util.h @@ -584,4 +584,5 @@ void VerifyForwardingClass(Agent *agent, struct TestForwardingClassData *data, uint32_t count); void VerifyQosConfig(Agent *agent, struct TestQosConfigData *data); void AddQosConfig(struct TestQosConfigData &data); +void AddQosQueue(const char *name, uint32_t id, uint32_t qos_queue_id); #endif // vnsw_agent_test_cmn_util_h diff --git a/src/vnsw/agent/test/test_util.cc b/src/vnsw/agent/test/test_util.cc index 2423db7d1b8..8e28a2919c6 100644 --- a/src/vnsw/agent/test/test_util.cc +++ b/src/vnsw/agent/test/test_util.cc @@ -4299,6 +4299,20 @@ void VerifyQosConfig(Agent *agent, struct TestQosConfigData *data) { data->default_forwarding_class_); } +void AddQosQueue(const char *name, uint32_t id, uint32_t qos_queue_id) { + + std::stringstream str; + str << "" << qos_queue_id << ""; + + char buf[10000]; + int len = 0; + memset(buf, 0, 10000); + AddXmlHdr(buf, len); + AddNodeString(buf, len, "qos-queue", name, id, str.str().c_str()); + AddXmlTail(buf, len); + ApplyXmlString(buf); +} + void AddGlobalConfig(struct TestForwardingClassData *data, uint32_t count) { std::stringstream str; diff --git a/src/vnsw/agent/vrouter/ksync/forwarding_class_ksync.cc b/src/vnsw/agent/vrouter/ksync/forwarding_class_ksync.cc index c388cccc547..2adfc0587cc 100644 --- a/src/vnsw/agent/vrouter/ksync/forwarding_class_ksync.cc +++ b/src/vnsw/agent/vrouter/ksync/forwarding_class_ksync.cc @@ -83,6 +83,16 @@ bool ForwardingClassKSyncEntry::Sync(DBEntry *e) { ret = true; } + uint16_t nic_queue = Agent::kInvalidQueueId; + if (fc->qos_queue_ref()) { + nic_queue = fc->qos_queue_ref()->nic_queue_id(); + } + + if (nic_queue_id_ != nic_queue) { + nic_queue_id_ = nic_queue; + ret = true; + } + return ret; } @@ -108,14 +118,7 @@ int ForwardingClassKSyncEntry::Encode(sandesh_op::type op, char *buf, int buf_le encoder.set_fmr_mpls_qos(mpls_exp_list); std::vector qos_queue_list; - const QosQueueKSyncEntry *qos_queue = - static_cast(qos_queue_ksync_.get()); - if (qos_queue) { - qos_queue_list.push_back(qos_queue->id()); - } else { - //Default for now - qos_queue_list.push_back(0); - } + qos_queue_list.push_back(nic_queue_id_); encoder.set_fmr_queue_id(qos_queue_list); int error = 0; diff --git a/src/vnsw/agent/vrouter/ksync/forwarding_class_ksync.h b/src/vnsw/agent/vrouter/ksync/forwarding_class_ksync.h index 4fd2359828b..1ddbcbf7d3a 100644 --- a/src/vnsw/agent/vrouter/ksync/forwarding_class_ksync.h +++ b/src/vnsw/agent/vrouter/ksync/forwarding_class_ksync.h @@ -50,6 +50,7 @@ class ForwardingClassKSyncEntry : public KSyncNetlinkDBEntry { uint32_t vlan_priority_; uint32_t mpls_exp_; KSyncEntryPtr qos_queue_ksync_; + uint16_t nic_queue_id_; DISALLOW_COPY_AND_ASSIGN(ForwardingClassKSyncEntry); };