diff options
author | Marian Chereji <marian.chereji@freescale.com> | 2013-06-18 13:07:37 (GMT) |
---|---|---|
committer | Fleming Andrew-AFLEMING <AFLEMING@freescale.com> | 2013-07-11 22:03:36 (GMT) |
commit | b4d23f5783a4887e2dda14570e47dc37c2c11f97 (patch) | |
tree | 5bc416629dc024127cf6dfae2417910b929e987e /drivers/staging | |
parent | 1ac9f7fc84ced02bba7248175062365be7460b0e (diff) | |
download | linux-fsl-qoriq-b4d23f5783a4887e2dda14570e47dc37c2c11f97.tar.xz |
dpa_offload: Add protection against concurrent HM ops runtime modifications
When modifying a header manipulation operation at runtime, the DPA
Classifier uses the FMD call FM_PCD_ManipNodeReplace. This function
locks the entire PCD and will fail if the PCD is already locked (it is
not a blocking function). The parallel access protection mechanism in DPA
Classifier would only protect against parallel access ON THE SAME MANIP
NODE. It used to ALLOW parallel access on DIFFERENT HM nodes, but this
will fail due to the locking system in the FMD.
This patch updates the locking mechanism in DPA Classifier for the HM
runtime modification functions so that a single call to
FM_PCD_ManipNodeReplace can happen at any one time.
Change-Id: I833b96e177e57f76d109ec000bd34c603df5ba71
Signed-off-by: Marian Chereji <marian.chereji@freescale.com>
Reviewed-on: http://git.am.freescale.net:8181/3007
Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
Reviewed-by: Bulie Radu-Andrei-B37577 <Radu.Bulie@freescale.com>
Reviewed-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com>
Diffstat (limited to 'drivers/staging')
-rw-r--r-- | drivers/staging/fsl_dpa_offload/dpa_classifier.c | 214 |
1 files changed, 173 insertions, 41 deletions
diff --git a/drivers/staging/fsl_dpa_offload/dpa_classifier.c b/drivers/staging/fsl_dpa_offload/dpa_classifier.c index 676f11c..956904c 100644 --- a/drivers/staging/fsl_dpa_offload/dpa_classifier.c +++ b/drivers/staging/fsl_dpa_offload/dpa_classifier.c @@ -4512,10 +4512,25 @@ int dpa_classif_modify_nat_hm(int hmd, return -EINVAL; } - LOCK_OBJECT(hm_array, hmd, pnat_hm, -EINVAL); + lock_desc_table(&hm_array); + pnat_hm = desc_to_object(&hm_array, hmd); + if (!pnat_hm) { + release_desc_table(&hm_array); + pr_err("ERROR: %s, %s (%d): Invalid descriptor (%d).\n", + __FILE__, __func__, __LINE__, hmd); + return -EINVAL; + } + mutex_lock(&pnat_hm->access); + /* + * Hold the lock on the descriptor table to prevent other runtime + * modifications of header manipulations until we're finished. The FMan + * driver doesn't allow parallel modification of HM nodes when they + * belong to the same PCD. + */ if (pnat_hm->type != DPA_CLS_HM_TYPE_NAT) { - RELEASE_OBJECT(pnat_hm); + release_desc_table(&hm_array); + mutex_unlock(&pnat_hm->access); pr_err("ERROR: %s, %s (%d): hmd=%d is not an NAT type " "header manip.\n", __FILE__, __func__, __LINE__, hmd); return -EINVAL; @@ -4525,7 +4540,8 @@ int dpa_classif_modify_nat_hm(int hmd, if (modify_flags & DPA_CLS_HM_NAT_MOD_SIP) { if (new_nat_params->nat.sip.version != pnat_hm->nat_params.nat.sip.version) { - RELEASE_OBJECT(pnat_hm); + release_desc_table(&hm_array); + mutex_unlock(&pnat_hm->access); pr_err("ERROR: %s, %s (%d): New SIP adress " "version (%d) in NAT header " "manipulation hmd=%d cannot be " @@ -4544,7 +4560,8 @@ int dpa_classif_modify_nat_hm(int hmd, if (modify_flags & DPA_CLS_HM_NAT_MOD_DIP) { if (new_nat_params->nat.dip.version != pnat_hm->nat_params.nat.dip.version) { - RELEASE_OBJECT(pnat_hm); + release_desc_table(&hm_array); + mutex_unlock(&pnat_hm->access); pr_err("ERROR: %s, %s (%d): New DIP adress " "version (%d) in NAT header " "manipulation hmd=%d cannot be " @@ -4582,7 +4599,8 @@ int dpa_classif_modify_nat_hm(int hmd, pnat_hm->nat_params.nat_pt. new_header.ipv4. options_size = 0; - RELEASE_OBJECT(pnat_hm); + release_desc_table(&hm_array); + mutex_unlock(&pnat_hm->access); pr_err("ERROR: %s, %s (%d): " "Out of memory while " "modifying IPv6 header " @@ -4649,7 +4667,8 @@ int dpa_classif_modify_nat_hm(int hmd, error = FM_PCD_ManipNodeReplace(hm_node->node, &new_hm_node_params); if (error != E_OK) { - RELEASE_OBJECT(pnat_hm); + release_desc_table(&hm_array); + mutex_unlock(&pnat_hm->access); pr_err("ERROR: %s, %s (%d): FMan " "driver call failed - " "FM_PCD_ManipNodeReplace, " @@ -4664,7 +4683,8 @@ int dpa_classif_modify_nat_hm(int hmd, } } - RELEASE_OBJECT(pnat_hm); + release_desc_table(&hm_array); + mutex_unlock(&pnat_hm->access); dpa_cls_dbg(("DEBUG: dpa_classifier %s (%d) <--\n", __func__, __LINE__)); @@ -4970,10 +4990,25 @@ int dpa_classif_modify_fwd_hm(int hmd, return -EINVAL; } - LOCK_OBJECT(hm_array, hmd, pfwd_hm, -EINVAL); + lock_desc_table(&hm_array); + pfwd_hm = desc_to_object(&hm_array, hmd); + if (!pfwd_hm) { + release_desc_table(&hm_array); + pr_err("ERROR: %s, %s (%d): Invalid descriptor (%d).\n", + __FILE__, __func__, __LINE__, hmd); + return -EINVAL; + } + mutex_lock(&pfwd_hm->access); + /* + * Hold the lock on the descriptor table to prevent other runtime + * modifications of header manipulations until we're finished. The FMan + * driver doesn't allow parallel modification of HM nodes when they + * belong to the same PCD. + */ if (pfwd_hm->type != DPA_CLS_HM_TYPE_FORWARDING) { - RELEASE_OBJECT(pfwd_hm); + release_desc_table(&hm_array); + mutex_unlock(&pfwd_hm->access); pr_err("ERROR: %s, %s (%d): hmd=%d is not an FORWARDING type " "header manip.\n", __FILE__, __func__, __LINE__, hmd); return -EINVAL; @@ -5078,7 +5113,8 @@ int dpa_classif_modify_fwd_hm(int hmd, error = FM_PCD_ManipNodeReplace(hm_node->node, &new_hm_node_params); if (error != E_OK) { - RELEASE_OBJECT(pfwd_hm); + release_desc_table(&hm_array); + mutex_unlock(&pfwd_hm->access); pr_err("ERROR: %s, %s (%d): FMan " "driver call failed - " "FM_PCD_ManipNodeReplace, " @@ -5093,7 +5129,8 @@ int dpa_classif_modify_fwd_hm(int hmd, } } - RELEASE_OBJECT(pfwd_hm); + release_desc_table(&hm_array); + mutex_unlock(&pfwd_hm->access); dpa_cls_dbg(("DEBUG: dpa_classifier %s (%d) <--\n", __func__, __LINE__)); @@ -5316,10 +5353,25 @@ int dpa_classif_modify_remove_hm(int hmd, return -EINVAL; } - LOCK_OBJECT(hm_array, hmd, premove_hm, -EINVAL); + lock_desc_table(&hm_array); + premove_hm = desc_to_object(&hm_array, hmd); + if (!premove_hm) { + release_desc_table(&hm_array); + pr_err("ERROR: %s, %s (%d): Invalid descriptor (%d).\n", + __FILE__, __func__, __LINE__, hmd); + return -EINVAL; + } + mutex_lock(&premove_hm->access); + /* + * Hold the lock on the descriptor table to prevent other runtime + * modifications of header manipulations until we're finished. The FMan + * driver doesn't allow parallel modification of HM nodes when they + * belong to the same PCD. + */ if (premove_hm->type != DPA_CLS_HM_TYPE_REMOVE) { - RELEASE_OBJECT(premove_hm); + release_desc_table(&hm_array); + mutex_unlock(&premove_hm->access); pr_err("ERROR: %s, %s (%d): hmd=%d is not an REMOVE type " "header manip.\n", __FILE__, __func__, __LINE__, hmd); return -EINVAL; @@ -5364,7 +5416,8 @@ int dpa_classif_modify_remove_hm(int hmd, error = FM_PCD_ManipNodeReplace(hm_node->node, &new_hm_node_params); if (error != E_OK) { - RELEASE_OBJECT(premove_hm); + release_desc_table(&hm_array); + mutex_unlock(&premove_hm->access); pr_err("ERROR: %s, %s (%d): FMan driver call " "failed - FM_PCD_ManipNodeReplace, " "while trying to modify hmd=%d, manip " @@ -5375,7 +5428,8 @@ int dpa_classif_modify_remove_hm(int hmd, } } - RELEASE_OBJECT(premove_hm); + release_desc_table(&hm_array); + mutex_unlock(&premove_hm->access); dpa_cls_dbg(("DEBUG: dpa_classifier %s (%d) <--\n", __func__, __LINE__)); @@ -5647,10 +5701,25 @@ int dpa_classif_modify_insert_hm(int hmd, return -EINVAL; } - LOCK_OBJECT(hm_array, hmd, pinsert_hm, -EINVAL); + lock_desc_table(&hm_array); + pinsert_hm = desc_to_object(&hm_array, hmd); + if (!pinsert_hm) { + release_desc_table(&hm_array); + pr_err("ERROR: %s, %s (%d): Invalid descriptor (%d).\n", + __FILE__, __func__, __LINE__, hmd); + return -EINVAL; + } + mutex_lock(&pinsert_hm->access); + /* + * Hold the lock on the descriptor table to prevent other runtime + * modifications of header manipulations until we're finished. The FMan + * driver doesn't allow parallel modification of HM nodes when they + * belong to the same PCD. + */ if (pinsert_hm->type != DPA_CLS_HM_TYPE_INSERT) { - RELEASE_OBJECT(pinsert_hm); + release_desc_table(&hm_array); + mutex_unlock(&pinsert_hm->access); pr_err("ERROR: %s, %s (%d): hmd=%d is not an INSERT type " "header manip.\n", __FILE__, __func__, __LINE__, hmd); return -EINVAL; @@ -5661,7 +5730,8 @@ int dpa_classif_modify_insert_hm(int hmd, DPA_CLS_HM_INS_MOD_PPPoE_HEADER; if ((modify_flags & mask) && (pinsert_hm->insert_params.type != DPA_CLS_HM_INSERT_ETHERNET)) { - RELEASE_OBJECT(pinsert_hm); + release_desc_table(&hm_array); + mutex_unlock(&pinsert_hm->access); pr_err("ERROR: %s, %s (%d): modify_flags=0x%x doesn't work on " "hmd=%d. It only works on INSERT ETHERNET header " "manipulations.\n", __FILE__, __func__, __LINE__, @@ -5673,7 +5743,8 @@ int dpa_classif_modify_insert_hm(int hmd, DPA_CLS_HM_INS_MOD_CUSTOM_DATA; if ((modify_flags & mask) && (pinsert_hm->insert_params.type != DPA_CLS_HM_INSERT_CUSTOM)) { - RELEASE_OBJECT(pinsert_hm); + release_desc_table(&hm_array); + mutex_unlock(&pinsert_hm->access); pr_err("ERROR: %s, %s (%d): modify_flags=0x%x doesn't work on " "hmd=%d. It only works on CUSTOM INSERT header " "manipulations.\n", __FILE__, __func__, __LINE__, @@ -5686,7 +5757,8 @@ int dpa_classif_modify_insert_hm(int hmd, new_insert_params->ppp_pid)) { if (pinsert_hm->insert_params.type != DPA_CLS_HM_INSERT_PPP) { - RELEASE_OBJECT(pinsert_hm); + release_desc_table(&hm_array); + mutex_unlock(&pinsert_hm->access); pr_err("ERROR: %s, %s (%d): modify_flags=0x%x doesn't " "work on hmd=%d. It only works on INSERT PPP " "header manipulations.\n", __FILE__, __func__, @@ -5718,7 +5790,8 @@ int dpa_classif_modify_insert_hm(int hmd, update = true; pdata = kzalloc(new_insert_params->custom.size, GFP_KERNEL); if (!pdata) { - RELEASE_OBJECT(pinsert_hm); + release_desc_table(&hm_array); + mutex_unlock(&pinsert_hm->access); pr_err("ERROR: %s, %s (%d): Not enough memory to " "adjust custom insert header manipulation.\n", __FILE__, __func__, __LINE__); @@ -5768,7 +5841,8 @@ int dpa_classif_modify_insert_hm(int hmd, error = FM_PCD_ManipNodeReplace(hm_node->node, &new_hm_node_params); if (error != E_OK) { - RELEASE_OBJECT(pinsert_hm); + release_desc_table(&hm_array); + mutex_unlock(&pinsert_hm->access); pr_err("ERROR: %s, %s (%d): FMan driver call " "failed - FM_PCD_ManipNodeReplace, " "while trying to modify hmd=%d, manip " @@ -5779,7 +5853,8 @@ int dpa_classif_modify_insert_hm(int hmd, } } - RELEASE_OBJECT(pinsert_hm); + release_desc_table(&hm_array); + mutex_unlock(&pinsert_hm->access); dpa_cls_dbg(("DEBUG: dpa_classifier %s (%d) <--\n", __func__, __LINE__)); @@ -6265,10 +6340,25 @@ int dpa_classif_modify_update_hm(int hmd, return -EINVAL; } - LOCK_OBJECT(hm_array, hmd, pupdate_hm, -EINVAL); + lock_desc_table(&hm_array); + pupdate_hm = desc_to_object(&hm_array, hmd); + if (!pupdate_hm) { + release_desc_table(&hm_array); + pr_err("ERROR: %s, %s (%d): Invalid descriptor (%d).\n", + __FILE__, __func__, __LINE__, hmd); + return -EINVAL; + } + mutex_lock(&pupdate_hm->access); + /* + * Hold the lock on the descriptor table to prevent other runtime + * modifications of header manipulations until we're finished. The FMan + * driver doesn't allow parallel modification of HM nodes when they + * belong to the same PCD. + */ if (pupdate_hm->type != DPA_CLS_HM_TYPE_UPDATE) { - RELEASE_OBJECT(pupdate_hm); + release_desc_table(&hm_array); + mutex_unlock(&pupdate_hm->access); pr_err("ERROR: %s, %s (%d): hmd=%d is not an UPDATE type " "header manip.\n", __FILE__, __func__, __LINE__, hmd); return -EINVAL; @@ -6298,7 +6388,8 @@ int dpa_classif_modify_update_hm(int hmd, new_ipv4_hdr.options) { pupdate_hm->update_params.replace. new_ipv4_hdr.options_size = 0; - RELEASE_OBJECT(pupdate_hm); + release_desc_table(&hm_array); + mutex_unlock(&pupdate_hm->access); pr_err("ERROR: %s, %s (%d): Out of " "memory while modifying IPv6 " "header replace header " @@ -6314,7 +6405,8 @@ int dpa_classif_modify_update_hm(int hmd, options_size = new_update_params->replace. new_ipv4_hdr.options_size; } else { - RELEASE_OBJECT(pupdate_hm); + release_desc_table(&hm_array); + mutex_unlock(&pupdate_hm->access); pr_err("ERROR: %s, %s (%d): modify_flags=0x%x doesn't " "work on hmd=%d. It only works on REPLACE " "header manipulations.\n", __FILE__, __func__, @@ -6331,7 +6423,8 @@ int dpa_classif_modify_update_hm(int hmd, if (new_update_params->update.l3.ipsa.version != pupdate_hm->update_params.update.l3.ipsa. version) { - RELEASE_OBJECT(pupdate_hm); + release_desc_table(&hm_array); + mutex_unlock(&pupdate_hm->access); pr_err("ERROR: %s, %s (%d): New SIP adress " "version (%d) in UPDATE header " "manipulation hmd=%d cannot be " @@ -6352,7 +6445,8 @@ int dpa_classif_modify_update_hm(int hmd, if (new_update_params->update.l3.ipda.version != pupdate_hm->update_params.update.l3.ipda. version) { - RELEASE_OBJECT(pupdate_hm); + release_desc_table(&hm_array); + mutex_unlock(&pupdate_hm->access); pr_err("ERROR: %s, %s (%d): New DIP adress " "version (%d) in UPDATE header " "manipulation hmd=%d cannot be " @@ -6438,7 +6532,8 @@ int dpa_classif_modify_update_hm(int hmd, error = FM_PCD_ManipNodeReplace(hm_node->node, &new_hm_node_params); if (error != E_OK) { - RELEASE_OBJECT(pupdate_hm); + release_desc_table(&hm_array); + mutex_unlock(&pupdate_hm->access); pr_err("ERROR: %s, %s (%d): FMan driver call " "failed - FM_PCD_ManipNodeReplace, " "while trying to modify hmd=%d, manip " @@ -6451,7 +6546,8 @@ int dpa_classif_modify_update_hm(int hmd, /* update[1] not supported at this time */ - RELEASE_OBJECT(pupdate_hm); + release_desc_table(&hm_array); + mutex_unlock(&pupdate_hm->access); dpa_cls_dbg(("DEBUG: dpa_classifier %s (%d) <--\n", __func__, __LINE__)); @@ -6741,10 +6837,25 @@ int dpa_classif_modify_vlan_hm(int hmd, return -EINVAL; } - LOCK_OBJECT(hm_array, hmd, pvlan_hm, -EINVAL); + lock_desc_table(&hm_array); + pvlan_hm = desc_to_object(&hm_array, hmd); + if (!pvlan_hm) { + release_desc_table(&hm_array); + pr_err("ERROR: %s, %s (%d): Invalid descriptor (%d).\n", + __FILE__, __func__, __LINE__, hmd); + return -EINVAL; + } + mutex_lock(&pvlan_hm->access); + /* + * Hold the lock on the descriptor table to prevent other runtime + * modifications of header manipulations until we're finished. The FMan + * driver doesn't allow parallel modification of HM nodes when they + * belong to the same PCD. + */ if (pvlan_hm->type != DPA_CLS_HM_TYPE_VLAN) { - RELEASE_OBJECT(pvlan_hm); + release_desc_table(&hm_array); + mutex_unlock(&pvlan_hm->access); pr_err("ERROR: %s, %s (%d): hmd=%d is not an VLAN type " "header manip.\n", __FILE__, __func__, __LINE__, hmd); return -EINVAL; @@ -6752,7 +6863,8 @@ int dpa_classif_modify_vlan_hm(int hmd, if (modify_flags == DPA_CLS_HM_VLAN_MOD_INGRESS_NUM_QTAGS) { if (pvlan_hm->vlan_params.type != DPA_CLS_HM_VLAN_INGRESS) { - RELEASE_OBJECT(pvlan_hm); + release_desc_table(&hm_array); + mutex_unlock(&pvlan_hm->access); pr_err("ERROR: %s, %s (%d): hmd=%d is not an INGRESS " "VLAN type header manipulation.\n", __FILE__, __func__, __LINE__, hmd); @@ -6767,7 +6879,8 @@ int dpa_classif_modify_vlan_hm(int hmd, } } else { if (pvlan_hm->vlan_params.type != DPA_CLS_HM_VLAN_EGRESS) { - RELEASE_OBJECT(pvlan_hm); + release_desc_table(&hm_array); + mutex_unlock(&pvlan_hm->access); pr_err("ERROR: %s, %s (%d): hmd=%d is not an EGRESS " "VLAN type header manipulation.\n", __FILE__, __func__, __LINE__, hmd); @@ -6828,7 +6941,8 @@ int dpa_classif_modify_vlan_hm(int hmd, error = FM_PCD_ManipNodeReplace(hm_node->node, &new_hm_node_params); if (error != E_OK) { - RELEASE_OBJECT(pvlan_hm); + release_desc_table(&hm_array); + mutex_unlock(&pvlan_hm->access); pr_err("ERROR: %s, %s (%d): FMan driver call " "failed - FM_PCD_ManipNodeReplace, " "while trying to modify hmd=%d, manip " @@ -6839,7 +6953,8 @@ int dpa_classif_modify_vlan_hm(int hmd, } } - RELEASE_OBJECT(pvlan_hm); + release_desc_table(&hm_array); + mutex_unlock(&pvlan_hm->access); dpa_cls_dbg(("DEBUG: dpa_classifier %s (%d) <--\n", __func__, __LINE__)); @@ -7079,10 +7194,25 @@ int dpa_classif_modify_mpls_hm(int hmd, return -EINVAL; } - LOCK_OBJECT(hm_array, hmd, pmpls_hm, -EINVAL); + lock_desc_table(&hm_array); + pmpls_hm = desc_to_object(&hm_array, hmd); + if (!pmpls_hm) { + release_desc_table(&hm_array); + pr_err("ERROR: %s, %s (%d): Invalid descriptor (%d).\n", + __FILE__, __func__, __LINE__, hmd); + return -EINVAL; + } + mutex_lock(&pmpls_hm->access); + /* + * Hold the lock on the descriptor table to prevent other runtime + * modifications of header manipulations until we're finished. The FMan + * driver doesn't allow parallel modification of HM nodes when they + * belong to the same PCD. + */ if (pmpls_hm->type != DPA_CLS_HM_TYPE_MPLS) { - RELEASE_OBJECT(pmpls_hm); + release_desc_table(&hm_array); + mutex_unlock(&pmpls_hm->access); pr_err("ERROR: %s, %s (%d): hmd=%d is not an MPLS type " "header manip.\n", __FILE__, __func__, __LINE__, hmd); return -EINVAL; @@ -7121,7 +7251,8 @@ int dpa_classif_modify_mpls_hm(int hmd, error = FM_PCD_ManipNodeReplace(hm_node->node, &new_hm_node_params); if (error != E_OK) { - RELEASE_OBJECT(pmpls_hm); + release_desc_table(&hm_array); + mutex_unlock(&pmpls_hm->access); pr_err("ERROR: %s, %s (%d): FMan driver call " "failed - FM_PCD_ManipNodeReplace, " "while trying to modify hmd=%d, manip " @@ -7132,7 +7263,8 @@ int dpa_classif_modify_mpls_hm(int hmd, } } - RELEASE_OBJECT(pmpls_hm); + release_desc_table(&hm_array); + mutex_unlock(&pmpls_hm->access); dpa_cls_dbg(("DEBUG: dpa_classifier %s (%d) <--\n", __func__, __LINE__)); |