-
Notifications
You must be signed in to change notification settings - Fork 388
[WIP] Obtain all possible outputs generated by ActionSelector group members with single input packet #1316
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] Obtain all possible outputs generated by ActionSelector group members with single input packet #1316
Changes from all commits
338c086
fcee16a
b2340c8
bc09a68
ce3eaf5
1cee0dc
728705b
7229247
caa8675
8acdc93
b51b374
d996808
cf186d3
2b29b2c
4c83c81
d56bfb5
02d89d9
207569e
5b0c47f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| /* Copyright 2013-present Contributors to the P4 Project | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| #ifndef BM_BM_SIM_FANOUT_PKT_MGR_H_ | ||
| #define BM_BM_SIM_FANOUT_PKT_MGR_H_ | ||
|
|
||
| #include "logger.h" | ||
| #include "packet.h" | ||
| #include "match_tables.h" | ||
| #include "action_profile.h" | ||
| #include <vector> | ||
|
|
||
| namespace bm { | ||
| class MatchTableIndirect; | ||
| using bm::ActionProfile; | ||
| using EntryVec = const std::vector<const ActionEntry*>; | ||
| using SelectorIface = ActionProfile::GroupSelectionIface; | ||
|
|
||
| struct FanoutCtx { | ||
| bool hit{false}; | ||
| std::vector<Packet *> fanout_pkts; | ||
| const Packet * cur_pkt{nullptr}; | ||
| ActionProfile *action_profile{nullptr}; | ||
| MatchTableIndirect *cur_table{nullptr}; | ||
| }; | ||
|
|
||
| class FanoutPktSelection: public SelectorIface{ | ||
| public: | ||
| using grp_hdl_t = ActionProfile::grp_hdl_t; | ||
| using mbr_hdl_t = ActionProfile::mbr_hdl_t; | ||
| using hash_t = ActionProfile::hash_t; | ||
| using MatchErrorCode = bm::MatchErrorCode; | ||
|
|
||
| FanoutPktSelection() = default; | ||
|
|
||
| // callbacks after member op, not actual member/group ops | ||
| void add_member_to_group(grp_hdl_t grp, mbr_hdl_t mbr) override; | ||
|
|
||
| void remove_member_from_group(grp_hdl_t grp, mbr_hdl_t mbr) override; | ||
|
|
||
| mbr_hdl_t get_from_hash(grp_hdl_t grp, hash_t h) const override; | ||
|
|
||
| void reset() override {} | ||
|
|
||
| private: | ||
| std::unordered_map<grp_hdl_t, std::vector<mbr_hdl_t>> groups; | ||
| }; | ||
|
|
||
| class FanoutPktMgr { | ||
| public: | ||
| FanoutPktMgr(const FanoutPktMgr&) = delete; | ||
| FanoutPktMgr& operator=(const FanoutPktMgr&) = delete; | ||
| static FanoutPktMgr& instance() { | ||
| static FanoutPktMgr instance_; | ||
| return instance_; | ||
| } | ||
|
|
||
| inline void register_thread(std::thread::id thread_id) { | ||
| BMLOG_DEBUG("Registering thread {}", thread_id); | ||
| fanout_ctx_map.emplace(thread_id, FanoutCtx()); | ||
| } | ||
| inline SelectorIface* get_grp_selector() { | ||
| return grp_selector; | ||
| } | ||
|
|
||
|
|
||
|
|
||
| std::vector<Packet *>& get_fanout_pkts(); | ||
| FanoutCtx& get_fanout_ctx(); | ||
| void set_ctx(MatchTableIndirect *table, const Packet &pkt, ActionProfile *action_profile, bool hit); | ||
| void reset_ctx(); | ||
| void replicate_for_entries(const std::vector<const ActionEntry*> &entries); | ||
|
|
||
| std::mutex fanout_pkt_mutex; | ||
| // TODO(Hao): deduplicate packets fanout, optional | ||
|
|
||
|
|
||
| private: | ||
| FanoutPktMgr() = default; | ||
| std::unordered_map<std::thread::id, FanoutCtx> fanout_ctx_map; | ||
| FanoutPktSelection fanout_selection; | ||
| SelectorIface* grp_selector{&fanout_selection}; | ||
| }; | ||
|
|
||
| } // namespace bm | ||
|
|
||
| #endif // BM_BM_SIM_FANOUT_PKT_MGR_H_ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,6 +22,8 @@ | |
| #include <bm/bm_sim/P4Objects.h> | ||
| #include <bm/bm_sim/phv.h> | ||
| #include <bm/bm_sim/actions.h> | ||
| #include <bm/bm_sim/logger.h> | ||
| #include <bm/bm_sim/fanout_pkt_mgr.h> | ||
|
|
||
| #include <iostream> | ||
| #include <istream> | ||
|
|
@@ -1655,8 +1657,20 @@ P4Objects::init_pipelines(const Json::Value &cfg_root, | |
| std::unique_ptr<ActionProfile> action_profile( | ||
| new ActionProfile(act_prof_name, act_prof_id, with_selection)); | ||
| if (with_selection) { | ||
| auto calc = process_cfg_selector(cfg_act_prof["selector"]); | ||
| action_profile->set_hash(std::move(calc)); | ||
| // TODO(Hao): clean debug logs | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove debug logs |
||
| BMLOG_DEBUG( | ||
| "Action profile '{}' with id {} has a selector", | ||
| act_prof_name, act_prof_id); | ||
|
|
||
| if(is_selector_fanout(cfg_act_prof["selector"])){ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Formatting: add space after "if" and before the ending "{" |
||
| BMLOG_DEBUG( | ||
| "Action profile '{}' with id {} enabled selector fanout", | ||
| act_prof_name, act_prof_id); | ||
| action_profile->set_selector_fanout(); | ||
| }else{ | ||
Hoooao marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| auto calc = process_cfg_selector(cfg_act_prof["selector"]); | ||
| action_profile->set_hash(std::move(calc)); | ||
| } | ||
|
Comment on lines
+1660
to
+1673
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if this should really be a command-line option for a target, instead of a special "algorithm" in the JSON. It feels like running in this "mode" should not require updating the JSON. Unless maybe the goal is to target individual selectors, and not all of them? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think ideally it would target individual selectors, though for our purposes I think it would be fine to only allow all-or-nothing for now if easier. That said, we felt the 'mode' was the best choice mostly because the other mode options are kinda non-sense in the presence of creating all outputs. E.g. what does it mean to hash a packet to a member when it should go to all of them? Or round-robin? So it seemed like it was just really a different selection scheme which is "Pick all". |
||
| } | ||
| add_action_profile(act_prof_name, std::move(action_profile)); | ||
| } | ||
|
|
@@ -2499,6 +2513,11 @@ P4Objects::check_hash(const std::string &name) const { | |
| return nullptr; | ||
| } | ||
|
|
||
| bool P4Objects::is_selector_fanout(const Json::Value &cfg_selector) const { | ||
| return cfg_selector.isMember("algo") && // not to hardcode names, fix later | ||
Hoooao marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| cfg_selector["algo"].asString() == "selector_fanout"; | ||
| } | ||
|
|
||
| std::unique_ptr<Calculation> | ||
| P4Objects::process_cfg_selector(const Json::Value &cfg_selector) const { | ||
| const auto selector_algo = cfg_selector["algo"].asString(); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,12 +22,14 @@ | |
| #include <bm/bm_sim/action_profile.h> | ||
| #include <bm/bm_sim/logger.h> | ||
| #include <bm/bm_sim/packet.h> | ||
| #include <bm/bm_sim/fanout_pkt_mgr.h> | ||
|
|
||
| #include <iostream> | ||
| #include <memory> | ||
| #include <string> | ||
| #include <vector> | ||
|
|
||
| #include <boost/stacktrace.hpp> // remove | ||
| namespace bm { | ||
|
|
||
| void | ||
|
|
@@ -126,6 +128,8 @@ ActionProfile::mbr_hdl_t | |
| ActionProfile::GroupMgr::get_from_hash(grp_hdl_t grp, hash_t h) const { | ||
| const auto &group_info = groups.at(grp); | ||
| auto s = group_info.size(); | ||
| BMLOG_DEBUG("Choosing member from group {} with hash {} (size {})", | ||
Hoooao marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| grp, h, s); | ||
| return group_info.get_nth(h % s); | ||
| } | ||
|
|
||
|
|
@@ -184,6 +188,28 @@ ActionProfile::lookup(const Packet &pkt, const IndirectIndex &index) const { | |
| return action_entries[mbr]; | ||
| } | ||
|
|
||
|
|
||
| std::vector<ActionProfile::mbr_hdl_t> | ||
| ActionProfile::get_all_mbrs_from_grp(grp_hdl_t grp) const { | ||
Hoooao marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| assert(is_valid_grp(grp)); | ||
| Group group; | ||
| MatchErrorCode rc = get_group(grp, &group); | ||
| _BM_UNUSED(rc); | ||
| assert(rc == MatchErrorCode::SUCCESS); | ||
| return group.mbr_handles; | ||
| } | ||
|
|
||
| std::vector<const ActionEntry*> | ||
| ActionProfile::get_entries_with_mbrs(const std::vector<ActionProfile::mbr_hdl_t> &mbrs) const { | ||
| std::vector<const ActionEntry*> entries; | ||
| entries.reserve(mbrs.size()); | ||
| for (auto m : mbrs) { | ||
| assert(is_valid_mbr(m)); | ||
| entries.push_back(&action_entries[m]); | ||
| } | ||
| return entries; | ||
| } | ||
|
|
||
| bool | ||
| ActionProfile::has_selection() const { return with_selection; } | ||
|
|
||
|
|
@@ -524,6 +550,10 @@ void | |
| ActionProfile::set_group_selector( | ||
| std::shared_ptr<GroupSelectionIface> selector) { | ||
| WriteLock lock = lock_write(); | ||
| BMLOG_DEBUG("Setting group selector for action profile '{}'", | ||
| get_name()); | ||
| // output stack trace, remove later | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove unnecessary debug logs |
||
| BMLOG_DEBUG("Stack trace: {}", boost::stacktrace::stacktrace()); | ||
| grp_selector_ = selector; | ||
| grp_selector = grp_selector_.get(); | ||
| } | ||
|
|
@@ -612,9 +642,18 @@ ActionProfile::ref_count_decrease(const IndirectIndex &index) { | |
|
|
||
| ActionProfile::mbr_hdl_t | ||
| ActionProfile::choose_from_group(grp_hdl_t grp, const Packet &pkt) const { | ||
| // TODO(Hao): PI resets to it own grp_selector, might be a bug, so I just sets | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you say a bit more on |
||
| // here for now.. | ||
| if(selector_fanout_enabled) { | ||
| return FanoutPktMgr::instance().get_grp_selector()->get_from_hash(grp, 0); | ||
| } | ||
| if (!hash) return grp_selector->get_from_hash(grp, 0); | ||
| hash_t h = static_cast<hash_t>(hash->output(pkt)); | ||
| return grp_selector->get_from_hash(grp, h); | ||
| } | ||
|
|
||
| void ActionProfile::set_selector_fanout(){ | ||
| selector_fanout_enabled = true; | ||
| } | ||
|
|
||
| } // namespace bm | ||
Uh oh!
There was an error while loading. Please reload this page.