[MEM] fix pkbuf problem in multi-threads (#1353)

We should use talloc in multi-threads instead of pkbuf.
Now, pkbuf library only uses single-thread environment.
This commit is contained in:
Sukchan Lee 2022-02-19 09:47:44 +09:00
parent 137ed99dd5
commit b4f382d360
8 changed files with 83 additions and 92 deletions

View File

@ -210,8 +210,6 @@ ogs_pkbuf_t *ogs_pkbuf_alloc_debug(
cluster->ref++;
ogs_thread_mutex_unlock(&pool->mutex);
pkbuf->cluster = cluster;
pkbuf->len = 0;
@ -225,6 +223,8 @@ ogs_pkbuf_t *ogs_pkbuf_alloc_debug(
pkbuf->pool = pool;
ogs_thread_mutex_unlock(&pool->mutex);
return pkbuf;
}
@ -237,11 +237,11 @@ void ogs_pkbuf_free(ogs_pkbuf_t *pkbuf)
pool = pkbuf->pool;
ogs_assert(pool);
ogs_thread_mutex_lock(&pool->mutex);
cluster = pkbuf->cluster;
ogs_assert(cluster);
ogs_thread_mutex_lock(&pool->mutex);
cluster->ref--;
if (cluster->ref == 0)
cluster_free(pool, pkbuf->cluster);

View File

@ -57,6 +57,7 @@ typedef enum {
typedef long S1AP_ProcedureCode_t;
typedef struct S1AP_S1AP_PDU ogs_s1ap_message_t;
typedef struct ogs_nas_eps_message_s ogs_nas_eps_message_t;
typedef struct ogs_diam_s6a_message_s ogs_diam_s6a_message_t;
typedef struct mme_vlr_s mme_vlr_t;
typedef struct mme_enb_s mme_enb_t;
typedef struct enb_ue_s enb_ue_t;
@ -84,6 +85,8 @@ typedef struct mme_event_s {
uint8_t nas_type;
ogs_nas_eps_message_t *nas_message;
ogs_diam_s6a_message_t *s6a_message;
mme_vlr_t *vlr;
mme_enb_t *enb;
enb_ue_t *enb_ue;

View File

@ -200,10 +200,8 @@ static void mme_s6a_aia_cb(void *data, struct msg **msg)
mme_event_t *e = NULL;
mme_ue_t *mme_ue = NULL;
ogs_pkbuf_t *s6abuf = NULL;
ogs_diam_s6a_message_t *s6a_message = NULL;
ogs_diam_s6a_aia_message_t *aia_message = NULL;
uint16_t s6abuf_len = 0;
ogs_diam_e_utran_vector_t *e_utran_vector = NULL;
ogs_debug("[MME] Authentication-Information-Answer");
@ -224,16 +222,9 @@ static void mme_s6a_aia_cb(void *data, struct msg **msg)
mme_ue = sess_data->mme_ue;
ogs_assert(mme_ue);
s6abuf_len = sizeof(ogs_diam_s6a_message_t);
ogs_assert(s6abuf_len < 8192);
s6abuf = ogs_pkbuf_alloc(NULL, s6abuf_len);
ogs_assert(s6abuf);
ogs_pkbuf_put(s6abuf, s6abuf_len);
s6a_message = (ogs_diam_s6a_message_t *)s6abuf->data;
ogs_assert(s6a_message);
/* Set Authentication-Information Command */
memset(s6a_message, 0, s6abuf_len);
s6a_message = ogs_calloc(1, sizeof(ogs_diam_s6a_message_t));
ogs_assert(s6a_message);
s6a_message->cmd_code = OGS_DIAM_S6A_CMD_CODE_AUTHENTICATION_INFORMATION;
aia_message = &s6a_message->aia_message;
ogs_assert(aia_message);
@ -385,11 +376,11 @@ out:
e = mme_event_new(MME_EVT_S6A_MESSAGE);
ogs_assert(e);
e->mme_ue = mme_ue;
e->pkbuf = s6abuf;
e->s6a_message = s6a_message;
rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) {
ogs_error("ogs_queue_push() failed:%d", (int)rv);
ogs_pkbuf_free(e->pkbuf);
ogs_free(s6a_message);
mme_event_free(e);
} else {
ogs_pollset_notify(ogs_app()->pollset);
@ -615,11 +606,9 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
mme_event_t *e = NULL;
mme_ue_t *mme_ue = NULL;
ogs_pkbuf_t *s6abuf = NULL;
ogs_diam_s6a_message_t *s6a_message = NULL;
ogs_diam_s6a_ula_message_t *ula_message = NULL;
ogs_subscription_data_t *subscription_data = NULL;
uint16_t s6abuf_len = 0;
ogs_debug("[MME] Update-Location-Answer");
@ -639,22 +628,15 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
mme_ue = sess_data->mme_ue;
ogs_assert(mme_ue);
s6abuf_len = sizeof(ogs_diam_s6a_message_t);
ogs_assert(s6abuf_len < 8192);
s6abuf = ogs_pkbuf_alloc(NULL, s6abuf_len);
ogs_assert(s6abuf);
ogs_pkbuf_put(s6abuf, s6abuf_len);
s6a_message = (ogs_diam_s6a_message_t *)s6abuf->data;
ogs_assert(s6a_message);
/* Set Authentication-Information Command */
memset(s6a_message, 0, s6abuf_len);
s6a_message = ogs_calloc(1, sizeof(ogs_diam_s6a_message_t));
ogs_assert(s6a_message);
s6a_message->cmd_code = OGS_DIAM_S6A_CMD_CODE_UPDATE_LOCATION;
ula_message = &s6a_message->ula_message;
ogs_assert(ula_message);
subscription_data = &ula_message->subscription_data;
ogs_assert(subscription_data);
/* AVP: 'Result-Code'(268)
* The Result-Code AVP indicates whether a particular request was completed
* successfully or whether an error occurred. The Result-Code data field
@ -1313,19 +1295,19 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
e = mme_event_new(MME_EVT_S6A_MESSAGE);
ogs_assert(e);
e->mme_ue = mme_ue;
e->pkbuf = s6abuf;
e->s6a_message = s6a_message;
rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) {
ogs_error("ogs_queue_push() failed:%d", (int)rv);
ogs_subscription_data_free(subscription_data);
ogs_pkbuf_free(e->pkbuf);
ogs_free(s6a_message);
mme_event_free(e);
} else {
ogs_pollset_notify(ogs_app()->pollset);
}
} else {
ogs_subscription_data_free(subscription_data);
ogs_pkbuf_free(s6abuf);
ogs_free(s6a_message);
}
/* Free the message */

View File

@ -77,7 +77,7 @@ void mme_s11_handle_echo_response(
}
void mme_s11_handle_create_session_response(
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid,
ogs_gtp_create_session_response_t *rsp)
{
int rv;
@ -87,6 +87,7 @@ void mme_s11_handle_create_session_response(
mme_bearer_t *bearer = NULL;
mme_sess_t *sess = NULL;
mme_ue_t *mme_ue = mme_ue_from_teid;
ogs_session_t *session = NULL;
ogs_gtp_bearer_qos_t bearer_qos;
ogs_gtp_ambr_t *ambr = NULL;
@ -99,9 +100,6 @@ void mme_s11_handle_create_session_response(
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
rv = ogs_gtp_xact_commit(xact);
ogs_expect_or_return(rv == OGS_OK);
if (rsp->pdn_address_allocation.presence == 0) {
ogs_error("No PDN Address Allocation");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
@ -132,6 +130,9 @@ void mme_s11_handle_create_session_response(
ogs_assert(mme_ue);
}
rv = ogs_gtp_xact_commit(xact);
ogs_expect_or_return(rv == OGS_OK);
if (rsp->cause.presence) {
ogs_gtp_cause_t *cause = rsp->cause.data;
ogs_assert(cause);
@ -168,13 +169,15 @@ void mme_s11_handle_create_session_response(
}
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
if (mme_ue && UE_CONTEXT_IN_ATTACH(mme_ue)) {
ogs_error("[%s] Attach reject", mme_ue->imsi_bcd);
ogs_assert(OGS_OK ==
nas_eps_send_attach_reject(mme_ue,
EMM_CAUSE_NETWORK_FAILURE, ESM_CAUSE_NETWORK_FAILURE));
if (mme_ue_from_teid && mme_ue) {
if (UE_CONTEXT_IN_ATTACH(mme_ue)) {
ogs_error("[%s] Attach reject", mme_ue->imsi_bcd);
ogs_assert(OGS_OK ==
nas_eps_send_attach_reject(mme_ue,
EMM_CAUSE_NETWORK_FAILURE, ESM_CAUSE_NETWORK_FAILURE));
}
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
}
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
return;
}
@ -256,12 +259,13 @@ void mme_s11_handle_create_session_response(
}
void mme_s11_handle_modify_bearer_response(
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid,
ogs_gtp_modify_bearer_response_t *rsp)
{
int rv;
uint8_t cause_value = 0;
mme_ue_t *mme_ue = mme_ue_from_teid;
mme_sess_t *sess = NULL;
mme_bearer_t *bearer = NULL;
@ -272,9 +276,6 @@ void mme_s11_handle_modify_bearer_response(
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
rv = ogs_gtp_xact_commit(xact);
ogs_expect_or_return(rv == OGS_OK);
if (!mme_ue) {
ogs_warn("No Context in TEID");
bearer = xact->data;
@ -285,6 +286,9 @@ void mme_s11_handle_modify_bearer_response(
ogs_assert(mme_ue);
}
rv = ogs_gtp_xact_commit(xact);
ogs_expect_or_return(rv == OGS_OK);
if (rsp->cause.presence) {
ogs_gtp_cause_t *cause = rsp->cause.data;
ogs_assert(cause);
@ -298,7 +302,8 @@ void mme_s11_handle_modify_bearer_response(
}
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
if (mme_ue_from_teid && mme_ue)
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
return;
}
@ -317,12 +322,13 @@ void mme_s11_handle_modify_bearer_response(
}
void mme_s11_handle_delete_session_response(
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid,
ogs_gtp_delete_session_response_t *rsp)
{
int rv;
uint8_t cause_value = 0;
int action = 0;
mme_ue_t *mme_ue = mme_ue_from_teid;
mme_sess_t *sess = NULL;
ogs_assert(xact);
@ -332,14 +338,14 @@ void mme_s11_handle_delete_session_response(
ogs_debug("Delete Session Response");
rv = ogs_gtp_xact_commit(xact);
ogs_expect_or_return(rv == OGS_OK);
sess = xact->data;
ogs_assert(sess);
mme_ue = sess->mme_ue;
ogs_assert(mme_ue);
rv = ogs_gtp_xact_commit(xact);
ogs_expect_or_return(rv == OGS_OK);
if (rsp->cause.presence) {
ogs_gtp_cause_t *cause = rsp->cause.data;
ogs_assert(cause);
@ -771,7 +777,7 @@ void mme_s11_handle_delete_bearer_request(
}
void mme_s11_handle_release_access_bearers_response(
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid,
ogs_gtp_release_access_bearers_response_t *rsp)
{
int rv;
@ -779,6 +785,7 @@ void mme_s11_handle_release_access_bearers_response(
int action = 0;
enb_ue_t *enb_ue = NULL;
mme_ue_t *mme_ue = mme_ue_from_teid;
mme_sess_t *sess = NULL;
mme_bearer_t *bearer = NULL;
@ -807,6 +814,7 @@ void mme_s11_handle_release_access_bearers_response(
ogs_warn("GTP Failed [CAUSE:%d]", cause_value);
}
ogs_assert(mme_ue);
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid);
@ -1037,11 +1045,12 @@ void mme_s11_handle_downlink_data_notification(
}
void mme_s11_handle_create_indirect_data_forwarding_tunnel_response(
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid,
ogs_gtp_create_indirect_data_forwarding_tunnel_response_t *rsp)
{
int rv;
uint8_t cause_value = 0;
mme_ue_t *mme_ue = mme_ue_from_teid;
mme_bearer_t *bearer = NULL;
enb_ue_t *source_ue = NULL;
int i;
@ -1071,11 +1080,13 @@ void mme_s11_handle_create_indirect_data_forwarding_tunnel_response(
ogs_warn("GTP Failed [CAUSE:%d]", cause_value);
}
ogs_assert(mme_ue);
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid);
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
if (mme_ue_from_teid && mme_ue)
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
return;
}
@ -1115,12 +1126,13 @@ void mme_s11_handle_create_indirect_data_forwarding_tunnel_response(
}
void mme_s11_handle_delete_indirect_data_forwarding_tunnel_response(
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid,
ogs_gtp_delete_indirect_data_forwarding_tunnel_response_t *rsp)
{
int rv;
uint8_t cause_value = 0;
int action = 0;
mme_ue_t *mme_ue = mme_ue_from_teid;
ogs_assert(xact);
action = xact->delete_indirect_action;
@ -1148,7 +1160,8 @@ void mme_s11_handle_delete_indirect_data_forwarding_tunnel_response(
}
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
if (mme_ue_from_teid && mme_ue)
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
return;
}
@ -1169,7 +1182,7 @@ void mme_s11_handle_delete_indirect_data_forwarding_tunnel_response(
}
void mme_s11_handle_bearer_resource_failure_indication(
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid,
ogs_gtp_bearer_resource_failure_indication_t *ind)
{
int rv;
@ -1177,12 +1190,18 @@ void mme_s11_handle_bearer_resource_failure_indication(
mme_bearer_t *bearer = NULL;
mme_sess_t *sess = NULL;
mme_ue_t *mme_ue = mme_ue_from_teid;
ogs_assert(xact);
bearer = xact->data;
ogs_assert(ind);
sess = bearer->sess;
ogs_assert(sess);
if (!mme_ue) {
ogs_warn("No Context in TEID");
mme_ue = sess->mme_ue;
ogs_assert(mme_ue);
}
ogs_debug("Bearer Resource Failure Indication");

View File

@ -119,7 +119,6 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
mme_bearer_t *default_bearer = NULL;
mme_sess_t *sess = NULL;
ogs_pkbuf_t *s6abuf = NULL;
ogs_diam_s6a_message_t *s6a_message = NULL;
ogs_gtp_node_t *gnode = NULL;
@ -430,22 +429,25 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
case MME_EVT_S6A_MESSAGE:
mme_ue = e->mme_ue;
ogs_assert(mme_ue);
s6abuf = e->pkbuf;
ogs_assert(s6abuf);
s6a_message = (ogs_diam_s6a_message_t *)s6abuf->data;
s6a_message = e->s6a_message;
ogs_assert(s6a_message);
ogs_warn("%p, %d, %p, %p", s6a_message, s6a_message->result_code,
s6a_message->err, s6a_message->exp_err);
enb_ue = enb_ue_cycle(mme_ue->enb_ue);
if (!enb_ue) {
ogs_error("S1 context has already been removed");
ogs_subscription_data_free(
&s6a_message->ula_message.subscription_data);
ogs_pkbuf_free(s6abuf);
ogs_free(s6a_message);
break;
}
if (s6a_message->result_code != ER_DIAMETER_SUCCESS) {
ogs_warn("%p, %d, %p, %p", s6a_message, s6a_message->result_code,
s6a_message->err, s6a_message->exp_err);
/* Unfortunately fd doesn't distinguish
* between result-code and experimental-result-code.
*
@ -467,7 +469,7 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
ogs_subscription_data_free(
&s6a_message->ula_message.subscription_data);
ogs_pkbuf_free(s6abuf);
ogs_free(s6a_message);
break;
}
@ -507,7 +509,7 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
break;
}
ogs_subscription_data_free(&s6a_message->ula_message.subscription_data);
ogs_pkbuf_free(s6abuf);
ogs_free(s6a_message);
break;
case MME_EVT_S11_MESSAGE:

View File

@ -31,6 +31,7 @@ typedef struct ogs_gtp_xact_s ogs_gtp_xact_t;
typedef struct ogs_pfcp_node_s ogs_pfcp_node_t;
typedef struct ogs_pfcp_xact_s ogs_pfcp_xact_t;
typedef struct ogs_pfcp_message_s ogs_pfcp_message_t;
typedef struct ogs_diam_gx_message_s ogs_diam_gx_message_t;
typedef struct smf_sess_s smf_sess_t;
typedef struct smf_upf_s smf_upf_t;
typedef struct ogs_sbi_request_s ogs_sbi_request_t;
@ -78,6 +79,8 @@ typedef struct smf_event_s {
ogs_pfcp_xact_t *pfcp_xact;
ogs_pfcp_message_t *pfcp_message;
ogs_diam_gx_message_t *gx_message;
struct {
ogs_sbi_request_t *request;
ogs_sbi_response_t *response;

View File

@ -646,9 +646,7 @@ static void smf_gx_cca_cb(void *data, struct msg **msg)
smf_event_t *e = NULL;
ogs_gtp_xact_t *xact = NULL;
smf_sess_t *sess = NULL;
ogs_pkbuf_t *gxbuf = NULL;
ogs_diam_gx_message_t *gx_message = NULL;
uint16_t gxbuf_len = 0;
uint32_t cc_request_number = 0;
ogs_debug("[Credit-Control-Answer]");
@ -689,16 +687,10 @@ static void smf_gx_cca_cb(void *data, struct msg **msg)
sess = sess_data->sess;
ogs_assert(sess);
gxbuf_len = sizeof(ogs_diam_gx_message_t);
ogs_assert(gxbuf_len < 8192);
gxbuf = ogs_pkbuf_alloc(NULL, gxbuf_len);
ogs_assert(gxbuf);
ogs_pkbuf_put(gxbuf, gxbuf_len);
gx_message = (ogs_diam_gx_message_t *)gxbuf->data;
gx_message = ogs_calloc(1, sizeof(ogs_diam_gx_message_t));
ogs_assert(gx_message);
/* Set Credit Control Command */
memset(gx_message, 0, gxbuf_len);
gx_message->cmd_code = OGS_DIAM_GX_CMD_CODE_CREDIT_CONTROL;
/* Value of Result Code */
@ -951,20 +943,20 @@ out:
ogs_assert(e);
e->sess = sess;
e->pkbuf = gxbuf;
e->gx_message = gx_message;
e->gtp_xact = xact;
rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) {
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
ogs_session_data_free(&gx_message->session_data);
ogs_pkbuf_free(e->pkbuf);
ogs_free(gx_message);
smf_event_free(e);
} else {
ogs_pollset_notify(ogs_app()->pollset);
}
} else {
ogs_session_data_free(&gx_message->session_data);
ogs_pkbuf_free(gxbuf);
ogs_free(gx_message);
}
/* Free the message */
@ -1047,8 +1039,6 @@ static int smf_gx_rar_cb( struct msg **msg, struct avp *avp,
struct sess_state *sess_data = NULL;
smf_event_t *e = NULL;
uint16_t gxbuf_len = 0;
ogs_pkbuf_t *gxbuf = NULL;
smf_sess_t *sess = NULL;
ogs_diam_gx_message_t *gx_message = NULL;
@ -1059,16 +1049,10 @@ static int smf_gx_rar_cb( struct msg **msg, struct avp *avp,
ogs_debug("Re-Auth-Request");
gxbuf_len = sizeof(ogs_diam_gx_message_t);
ogs_assert(gxbuf_len < 8192);
gxbuf = ogs_pkbuf_alloc(NULL, gxbuf_len);
ogs_assert(gxbuf);
ogs_pkbuf_put(gxbuf, gxbuf_len);
gx_message = (ogs_diam_gx_message_t *)gxbuf->data;
gx_message = ogs_calloc(1, sizeof(ogs_diam_gx_message_t));
ogs_assert(gx_message);
/* Set Credit Control Command */
memset(gx_message, 0, gxbuf_len);
gx_message->cmd_code = OGS_DIAM_GX_CMD_RE_AUTH;
/* Create answer header */
@ -1203,12 +1187,12 @@ static int smf_gx_rar_cb( struct msg **msg, struct avp *avp,
ogs_assert(e);
e->sess = sess;
e->pkbuf = gxbuf;
e->gx_message = gx_message;
rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) {
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
ogs_session_data_free(&gx_message->session_data);
ogs_pkbuf_free(e->pkbuf);
ogs_free(gx_message);
smf_event_free(e);
} else {
ogs_pollset_notify(ogs_app()->pollset);
@ -1263,7 +1247,7 @@ out:
ogs_assert(ret == 0);
ogs_session_data_free(&gx_message->session_data);
ogs_pkbuf_free(gxbuf);
ogs_free(gx_message);
return 0;
}

View File

@ -232,9 +232,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
case SMF_EVT_GX_MESSAGE:
ogs_assert(e);
recvbuf = e->pkbuf;
ogs_assert(recvbuf);
gx_message = (ogs_diam_gx_message_t *)recvbuf->data;
gx_message = e->gx_message;
ogs_assert(gx_message);
sess = e->sess;
@ -269,7 +267,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
}
ogs_session_data_free(&gx_message->session_data);
ogs_pkbuf_free(recvbuf);
ogs_free(gx_message);
break;
case SMF_EVT_N4_MESSAGE:
ogs_assert(e);