Skip to content

Commit

Permalink
Revert changes of sched touching from softirq context
Browse files Browse the repository at this point in the history
Signed-off-by: Aleksey Mikhaylov <[email protected]>
  • Loading branch information
ttaym committed Apr 21, 2022
1 parent e129b19 commit 18a1c47
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 66 deletions.
28 changes: 8 additions & 20 deletions fw/http_sched_hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -403,40 +403,28 @@ tfw_sched_hash_put_srv_data(struct rcu_head *rcu)
}

static int
tfw_sched_hash_srv_setup(TfwServer *srv)
tfw_sched_hash_add_srv(TfwServer *srv)
{
size_t size, seed, seed_inc = 0;
TfwHashConnList *cl = rcu_dereference_bh_check(srv->sched_data, 1);
TfwHashConnList *cl_copy;
TfwHashConnList *cl = rcu_dereference_check(srv->sched_data, 1);

if (unlikely(cl))
return -EEXIST;

seed = get_random_long();
seed_inc = get_random_int();

size = sizeof(TfwHashConnList) + srv->conn_n * sizeof(TfwHashConn);
if (!(cl_copy = kzalloc(size, in_task() ? GFP_KERNEL : GFP_ATOMIC)))
if (!(cl = kzalloc(size, GFP_KERNEL)))
return -ENOMEM;

tfw_sched_hash_add_conns(srv, cl_copy, &seed, seed_inc);

rcu_assign_pointer(srv->sched_data, cl_copy);
tfw_sched_hash_add_conns(srv, cl, &seed, seed_inc);

if (cl)
call_rcu(&cl->rcu, tfw_sched_hash_put_srv_data);
rcu_assign_pointer(srv->sched_data, cl);

return 0;
}

static int
tfw_sched_hash_add_srv(TfwServer *srv)
{
TfwHashConnList *cl = rcu_dereference_check(srv->sched_data, 1);

if (unlikely(cl))
return -EEXIST;

return tfw_sched_hash_srv_setup(srv);
}

static void
tfw_sched_hash_del_srv(TfwServer *srv)
{
Expand Down
65 changes: 19 additions & 46 deletions fw/http_sched_ratio.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,6 @@

#define TFW_SCHED_RATIO_INTVL (HZ / 20) /* The timer periodicity. */

typedef struct {
struct rcu_head rcu;
size_t conn_n;
TfwSrvConn *conns[0];
} TfwRatioSrvConnList;

/**
* Individual upstream server descriptor.
*
Expand All @@ -44,15 +38,17 @@ typedef struct {
*
* @rcu - RCU control structure.
* @srv - pointer to server structure.
* @cl - pointer to list of pointers to server connection structures.
* @conn - list of pointers to server connection structures.
* @counter - monotonic counter for choosing the next connection.
* @conn_n - number of connections to server.
* @seq - current sequence number for APM stats.
*/
typedef struct {
struct rcu_head rcu;
TfwServer *srv;
TfwRatioSrvConnList *cl;
TfwSrvConn **conn;
atomic64_t counter;
size_t conn_n;
unsigned int seq;
} TfwRatioSrvDesc;

Expand Down Expand Up @@ -831,12 +827,10 @@ static inline TfwSrvConn *
__sched_srv(TfwRatioSrvDesc *srvdesc, int skipnip, int *nipconn)
{
size_t ci;
TfwRatioSrvConnList *cl = rcu_dereference_bh_check(srvdesc->cl, 1);

rcu_read_lock_bh();
for (ci = 0; ci < cl->conn_n; ++ci) {
for (ci = 0; ci < srvdesc->conn_n; ++ci) {
unsigned long idxval = atomic64_inc_return(&srvdesc->counter);
TfwSrvConn *srv_conn = cl->conns[idxval % cl->conn_n];
TfwSrvConn *srv_conn = srvdesc->conn[idxval % srvdesc->conn_n];

if (unlikely(tfw_srv_conn_restricted(srv_conn)
|| tfw_srv_conn_unscheduled(srv_conn)
Expand All @@ -848,12 +842,9 @@ __sched_srv(TfwRatioSrvDesc *srvdesc, int skipnip, int *nipconn)
++(*nipconn);
continue;
}
if (likely(tfw_srv_conn_get_if_live(srv_conn))) {
rcu_read_unlock_bh();
if (likely(tfw_srv_conn_get_if_live(srv_conn)))
return srv_conn;
}
}
rcu_read_unlock_bh();

return NULL;
}
Expand Down Expand Up @@ -991,7 +982,7 @@ tfw_sched_ratio_cleanup(TfwRatio *ratio)

/* Data that is shared between pool entries. */
for (si = 0; si < ratio->srv_n; ++si)
kfree(ratio->srvdesc[si].cl);
kfree(ratio->srvdesc[si].conn);

kfree(ratio->hstdata);
kfree(ratio->rtodata);
Expand Down Expand Up @@ -1045,52 +1036,34 @@ tfw_sched_ratio_del_grp(TfwSrvGroup *sg)
call_rcu(&ratio->rcu, tfw_sched_ratio_cleanup_rcu_cb);
}

static void
tfw_sched_ratio_put_conn_data(struct rcu_head *rcu)
{
TfwRatioSrvConnList *cl = container_of(rcu, TfwRatioSrvConnList, rcu);
kfree(cl);
}

/**
* Add anew or update descriptor for server.
*
* Can be called from user context on (re-)configuration or from SoftIRQ context
* as well on websocket connection establishment to renew actual connection list.
*/
static int
tfw_sched_ratio_srvdesc_setup_srv(TfwServer *srv, TfwRatioSrvDesc *srvdesc)
{
size_t size, ci = 0;
TfwSrvConn *srv_conn;
TfwRatioSrvConnList *cl_copy;
TfwRatioSrvConnList *cl = rcu_dereference_bh_check(srvdesc->cl, 1);
TfwSrvConn **conn, *srv_conn;

size = sizeof(TfwRatioSrvConnList) + sizeof(TfwSrvConn *) * srv->conn_n;
if (!(cl_copy = kzalloc(size, in_task() ? GFP_KERNEL : GFP_ATOMIC)))
size = sizeof(TfwSrvConn *) * srv->conn_n;
if (!(srvdesc->conn = kzalloc(size, GFP_KERNEL)))
return -ENOMEM;

conn = srvdesc->conn;
list_for_each_entry(srv_conn, &srv->conn_list, list) {
if (tfw_srv_conn_unscheduled(srv_conn))
continue;
if (unlikely(ci++ == srv->conn_n))
goto err;

cl_copy->conns[ci-1] = srv_conn;
*conn++ = srv_conn;
}
if (unlikely(ci != srv->conn_n))
goto err;

cl_copy->conn_n = ci;
rcu_assign_pointer(srvdesc->srv, srv);
rcu_assign_pointer(srvdesc->cl, cl_copy);

if (cl)
call_rcu(&cl->rcu, tfw_sched_ratio_put_conn_data);
srvdesc->conn_n = srv->conn_n;
srvdesc->srv = srv;
atomic64_set(&srvdesc->counter, 0);

return 0;
err:
kfree(cl_copy);
kfree(srvdesc->conn);
return -EINVAL;
}

Expand All @@ -1111,7 +1084,7 @@ tfw_sched_ratio_srvdesc_setup(TfwSrvGroup *sg, TfwRatio *ratio)
int r;
size_t si = 0;
TfwServer *srv;
TfwRatioSrvDesc *srvdesc = rcu_dereference_bh_check(ratio->srvdesc, 1);
TfwRatioSrvDesc *srvdesc = ratio->srvdesc;

list_for_each_entry(srv, &sg->srv_list, list) {
if (unlikely((si++ == sg->srv_n) || !srv->conn_n
Expand Down Expand Up @@ -1307,7 +1280,7 @@ static void
tfw_sched_ratio_put_srv_data(struct rcu_head *rcu)
{
TfwRatioSrvDesc *srvdesc = container_of(rcu, TfwRatioSrvDesc, rcu);
kfree(srvdesc->cl);
kfree(srvdesc->conn);
kfree(srvdesc);
}

Expand Down

0 comments on commit 18a1c47

Please sign in to comment.