-
Notifications
You must be signed in to change notification settings - Fork 104
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
remove request from seq_list when errors occur #1110
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably the patch is good, just a couple of questions since we've been fixing bugs in the code for a while.
tempesta_fw/http.c
Outdated
@@ -2241,6 +2241,8 @@ __tfw_http_resp_fwd(TfwCliConn *cli_conn, struct list_head *ret_queue) | |||
BUG_ON(!req->resp); | |||
tfw_http_resp_init_ss_flags(req->resp, req); | |||
if (tfw_cli_conn_send(cli_conn, (TfwMsg *)req->resp)) { | |||
list_del_init(&req->msg.seq_list); | |||
tfw_http_resp_pair_free(req); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was supposed that tfw_http_resp_fwd()
takes care about the responses and linked requests in the final loop if !list_empty(&ret_queue))
- why do we need to free requests and responses here? Don't we need to adjust or completely remove the loop at the end of tfw_http_resp_fwd()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, tfw_http_resp_fwd()
takes care on unforwarded responses, and all the responses are destroyed there. The new line list_del_init(&req->msg.seq_list);
was missed there thought, so #1099 happen. This exact lines are not required here since we still do the same later during error handling at the end of tfw_http_resp_fwd()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need to free requests and responses here? Don't we need to adjust or completely remove the loop at the end of tfw_http_resp_fwd()?
It's possible to move all the lines from the loop to __tfw_http_resp_fwd()
, but there will be no simplification other than moving all reclamation code together. Now two sites are apart from each another. That's slightly confusing. However, that much is fine.
@@ -2347,6 +2349,9 @@ tfw_http_resp_fwd(TfwHttpResp *resp) | |||
TFW_DBG2("%s: Forwarding error: conn=[%p] resp=[%p]\n", | |||
__func__, cli_conn, req->resp); | |||
BUG_ON(!req->resp); | |||
spin_lock_bh(&cli_conn->seq_qlock); | |||
list_del_init(&req->msg.seq_list); | |||
spin_unlock_bh(&cli_conn->seq_qlock); | |||
tfw_http_resp_pair_free(req); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need the loop if we deleted all the requests in the patch above? Maybe it makes sense to write 2 lines instead of 4?
tfw_http_conn_msg_free(req->pair);
tfw_http_conn_req_clean(req);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After @ikoveshnikov's comment, I realized there is no need to lock, as code above extracts a part of the list. That part is now private, so here only a single list_del_init()
is required, without locking. There is no need to check whenever req->msg.seq_list
is empty — it's not, since we get req
by iterating over a list with req->msg.seq_list
in it. So tfw_http_conn_req_clean()
is unsuitable here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The patch adds duplicated code and unnecessary spinlock operations, which should be removed.
tempesta_fw/http.c
Outdated
@@ -2241,6 +2241,8 @@ __tfw_http_resp_fwd(TfwCliConn *cli_conn, struct list_head *ret_queue) | |||
BUG_ON(!req->resp); | |||
tfw_http_resp_init_ss_flags(req->resp, req); | |||
if (tfw_cli_conn_send(cli_conn, (TfwMsg *)req->resp)) { | |||
list_del_init(&req->msg.seq_list); | |||
tfw_http_resp_pair_free(req); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, tfw_http_resp_fwd()
takes care on unforwarded responses, and all the responses are destroyed there. The new line list_del_init(&req->msg.seq_list);
was missed there thought, so #1099 happen. This exact lines are not required here since we still do the same later during error handling at the end of tfw_http_resp_fwd()
.
tempesta_fw/http.c
Outdated
@@ -2347,6 +2349,9 @@ tfw_http_resp_fwd(TfwHttpResp *resp) | |||
TFW_DBG2("%s: Forwarding error: conn=[%p] resp=[%p]\n", | |||
__func__, cli_conn, req->resp); | |||
BUG_ON(!req->resp); | |||
spin_lock_bh(&cli_conn->seq_qlock); | |||
list_del_init(&req->msg.seq_list); | |||
spin_unlock_bh(&cli_conn->seq_qlock); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The list passed to __tfw_http_resp_fwd()
is not cli_conn->seq_queue
. The ret_queue
is cut from cli_conn->seq_queue
:
Line 2305 in 774869c
__list_cut_position(&ret_queue, seq_queue, req_retent); |
So the
req
is not a member of cli_conn->seq_queue
, and the spinlock is not required here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed. Removed.
2cb4f38
to
706c592
Compare
Updated patch according to the comments. Now it's just single |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing to add. Good to merge.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good to merge!
Adds missing error handling. If a request cannot be forwarded, it's dropped. In that case we need to remove it from the connection's queue.
(fixes #1099)