Skip to content

Commit 3e71995

Browse files
polycubed: fix packet out deadlock when attaching transparent cubes
A dead lock is possible when a transparent cube is added to a port and there is a packetout operation at the same time. If port1 and port2 are connected, a packetout operation is going on port1 and a cube is attached to port2 Thread1: | Thread2: port1->send_packet_out() | port2->add_cube() lock(port1) | lock(port2) ... | ... port2->get_index() | port1->set_next_index() lock(port2) | lock(port1) The main cause of this is that send_packet_out() uses get_index() that internally uses a lock. This commit modifies get_index() so it doesn't require to lock but returns a variable that is calculated before. Signed-off-by: Mauricio Vasquez B <mauriciovasquezbernal@gmail.com>
1 parent b64e0fa commit 3e71995

2 files changed

Lines changed: 7 additions & 5 deletions

File tree

src/polycubed/src/port.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,10 @@ uint16_t Port::index() const {
4949
}
5050

5151
uint16_t Port::get_index() const {
52-
std::lock_guard<std::mutex> guard(port_mutex_);
53-
return __get_index();
52+
return port_index_;
5453
}
5554

56-
uint16_t Port::__get_index() const {
55+
uint16_t Port::calculate_index() const {
5756
// check if there is ingress-enabled transparent cube
5857
for (auto it = cubes_.rbegin(); it != cubes_.rend(); ++it) {
5958
auto index = (*it)->get_index(ProgramType::INGRESS);
@@ -230,9 +229,11 @@ void Port::update_indexes() {
230229
}
231230
}
232231

232+
port_index_ = calculate_index();
233+
233234
// CASE4: peer -> cube[N-1]
234235
if (peer_port_) {
235-
peer_port_->set_next_index(__get_index());
236+
peer_port_->set_next_index(port_index_);
236237
}
237238

238239
// egress chain: port -> cubes[0] -> ... -> cube[N -1] -> peer

src/polycubed/src/port.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ class Port : public polycube::service::PortIface, public PeerIface {
100100
std::shared_ptr<spdlog::logger> logger;
101101

102102
private:
103-
uint16_t __get_index() const;
103+
uint16_t port_index_; // ebpf id used by other modules to call this port
104+
uint16_t calculate_index() const;
104105
};
105106

106107
} // namespace polycubed

0 commit comments

Comments
 (0)