Skip to content

Commit

Permalink
Add the unlink argument to ss_send() (#56)
Browse files Browse the repository at this point in the history
This part of a series of changes to implement #56.
The kernel is modified to not free SKBs that are still in Tempesta
queues. That gives Tempesta control over SKBs. Request SKBs are kept
until a corresponging response it received. However. when response
is sent to a client, its SKBs are no longer needed. The new argument
tells ss_send() if it needs to remove SKBs from a Tempesta queue.
  • Loading branch information
keshonok committed Jul 28, 2015
1 parent 7b6764f commit 1a8399b
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 16 deletions.
4 changes: 2 additions & 2 deletions tempesta_fw/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,9 @@ tfw_connection_destruct(TfwConnection *conn)
}

void
tfw_connection_send(TfwConnection *conn, TfwMsg *msg)
tfw_connection_send(TfwConnection *conn, TfwMsg *msg, int unlink)
{
ss_send(conn->sk, &msg->skb_list);
ss_send(conn->sk, &msg->skb_list, unlink);
}

/*
Expand Down
14 changes: 13 additions & 1 deletion tempesta_fw/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,19 @@ tfw_connection_validate_cleanup(TfwConnection *conn)
}

void tfw_connection_hooks_register(TfwConnHooks *hooks, int type);
void tfw_connection_send(TfwConnection *conn, TfwMsg *msg);
void tfw_connection_send(TfwConnection *conn, TfwMsg *msg, int unlink);

static inline void
tfw_connection_send_req(TfwConnection *conn, TfwMsg *msg)
{
tfw_connection_send(conn, msg, 0);
}

static inline void
tfw_connection_send_resp(TfwConnection *conn, TfwMsg *msg)
{
tfw_connection_send(conn, msg, 1);
}

/* Generic helpers, used for both client and server connections. */
void tfw_connection_init(TfwConnection *conn);
Expand Down
10 changes: 5 additions & 5 deletions tempesta_fw/http.c
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ tfw_http_send_404(TfwHttpMsg *hm)
return -1;
}
TFW_DBG("Send HTTP 404 response to the client\n");
tfw_connection_send(conn, (TfwMsg *)resp);
tfw_connection_send_resp(conn, (TfwMsg *)resp);
tfw_http_msg_free(resp);

return 0;
Expand All @@ -465,7 +465,7 @@ tfw_http_send_500(TfwHttpMsg *hm)
return -1;
}
TFW_DBG("Send HTTP 500 response to the client\n");
tfw_connection_send(conn, (TfwMsg *)resp);
tfw_connection_send_resp(conn, (TfwMsg *)resp);
tfw_http_msg_free(resp);

return 0;
Expand Down Expand Up @@ -1195,7 +1195,7 @@ tfw_http_req_cache_cb(TfwHttpReq *req, TfwHttpResp *resp, void *data)
* We have prepared response, send it as is.
* TODO should we adjust it somehow?
*/
tfw_connection_send(req->conn, (TfwMsg *)resp);
tfw_connection_send_resp(req->conn, (TfwMsg *)resp);
} else {
/* Dispatch request to an appropriate server. */
TfwConnection *conn = tfw_sched_get_srv_conn((TfwMsg *)req);
Expand All @@ -1218,7 +1218,7 @@ tfw_http_req_cache_cb(TfwHttpReq *req, TfwHttpResp *resp, void *data)
list_add_tail(&req->msg.msg_list, &conn->msg_queue);

/* Send request to the server. */
tfw_connection_send(conn, (TfwMsg *)req);
tfw_connection_send_req(conn, (TfwMsg *)req);
}
return;

Expand Down Expand Up @@ -1461,7 +1461,7 @@ tfw_http_resp_process(TfwConnection *conn, struct sk_buff *skb,
* The cache frees the response and the request.
* conn->msg will get NULLed in the process.
*/
tfw_connection_send(hmreq->conn, (TfwMsg *)hmresp);
tfw_connection_send_resp(hmreq->conn, (TfwMsg *)hmresp);
tfw_cache_add((TfwHttpResp *)hmresp, (TfwHttpReq *)hmreq);

return TFW_PASS;
Expand Down
4 changes: 2 additions & 2 deletions tempesta_fw/http_sticky.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ tfw_http_sticky_send_302(TfwHttpMsg *hm)
if ((resp = tfw_http_prep_302(hm, &cookie)) == NULL) {
return -1;
}
tfw_connection_send(conn, (TfwMsg *)resp);
tfw_connection_send_resp(conn, (TfwMsg *)resp);
tfw_http_msg_free(resp);

return 0;
Expand All @@ -90,7 +90,7 @@ tfw_http_sticky_send_502(TfwHttpMsg *hm)
if ((resp = tfw_http_prep_502(hm)) == NULL) {
return -1;
}
tfw_connection_send(conn, (TfwMsg *)resp);
tfw_connection_send_resp(conn, (TfwMsg *)resp);
tfw_http_msg_free(resp);

return 0;
Expand Down
14 changes: 9 additions & 5 deletions tempesta_fw/sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,9 @@ ss_skb_route(struct sk_buff *skb, struct tcp_sock *tp)
* TODO use MSG_MORE untill we reach end of message.
*/
void
ss_send(struct sock *sk, const SsSkbList *skb_list)
ss_send(struct sock *sk, SsSkbList *skb_list, int unlink)
{
struct sk_buff *skb;
struct sk_buff *skb, *nskb;
struct tcp_skb_cb *tcb;
struct tcp_sock *tp = tcp_sk(sk);
int flags = MSG_DONTWAIT; /* we can't sleep */
Expand All @@ -143,15 +143,19 @@ ss_send(struct sock *sk, const SsSkbList *skb_list)
SS_DBG("%s: sk %p, sk->sk_socket %p, state (%s)\n",
__FUNCTION__, sk, sk->sk_socket, ss_statename[sk->sk_state]);

/* Synchronize concurrent socket writting in different softirqs. */
/* Synchronize concurrent socket writes in different softirqs. */
bh_lock_sock_nested(sk);

mss_now = tcp_send_mss(sk, &size_goal, flags);

BUG_ON(ss_skb_queue_empty(skb_list));
for (skb = ss_skb_peek(skb_list), tcb = TCP_SKB_CB(skb);
skb; skb = ss_skb_next(skb_list, skb))
for (skb = ss_skb_peek(skb_list), tcb = TCP_SKB_CB(skb),
nskb = ss_skb_next(skb_list, skb); skb;
skb = nskb, nskb = nskb ? ss_skb_next(skb_list, nskb) : NULL)
{
if (unlink)
ss_skb_unlink(skb_list, skb);

skb->ip_summed = CHECKSUM_PARTIAL;
skb_shinfo(skb)->gso_segs = 0;

Expand Down
2 changes: 1 addition & 1 deletion tempesta_fw/sync_socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ void ss_proto_init(SsProto *proto, const SsHooks *hooks, int type);
void ss_proto_inherit(const SsProto *parent, SsProto *child, int child_type);
void ss_set_callbacks(struct sock *sk);
void ss_set_listen(struct sock *sk);
void ss_send(struct sock *sk, const SsSkbList *skb_list);
void ss_send(struct sock *sk, SsSkbList *skb_list, int unlink);
void ss_close(struct sock *sk);
int ss_sock_create(int family, int type, int protocol, struct sock **res);
void ss_release(struct sock *sk);
Expand Down

0 comments on commit 1a8399b

Please sign in to comment.