mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-28 11:57:28 +00:00
Copy and clear the reply descriptor atomically. This prevents concurrency
in the interrupt handlers (usually due to timeout/error recovery) from seeing and processing the same descriptor twice.
This commit is contained in:
parent
44f299a3cc
commit
617e85f387
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=341755
@ -2493,12 +2493,13 @@ void
|
||||
mpr_intr_locked(void *data)
|
||||
{
|
||||
MPI2_REPLY_DESCRIPTORS_UNION *desc;
|
||||
MPI2_DIAG_RELEASE_REPLY *rel_rep;
|
||||
mpr_fw_diagnostic_buffer_t *pBuffer;
|
||||
struct mpr_softc *sc;
|
||||
uint64_t tdesc;
|
||||
struct mpr_command *cm = NULL;
|
||||
uint8_t flags;
|
||||
u_int pq;
|
||||
MPI2_DIAG_RELEASE_REPLY *rel_rep;
|
||||
mpr_fw_diagnostic_buffer_t *pBuffer;
|
||||
|
||||
sc = (struct mpr_softc *)data;
|
||||
|
||||
@ -2510,6 +2511,17 @@ mpr_intr_locked(void *data)
|
||||
for ( ;; ) {
|
||||
cm = NULL;
|
||||
desc = &sc->post_queue[sc->replypostindex];
|
||||
|
||||
/*
|
||||
* Copy and clear out the descriptor so that any reentry will
|
||||
* immediately know that this descriptor has already been
|
||||
* looked at. There is unfortunate casting magic because the
|
||||
* MPI API doesn't have a cardinal 64bit type.
|
||||
*/
|
||||
tdesc = 0xffffffffffffffff;
|
||||
tdesc = atomic_swap_64((uint64_t *)desc, tdesc);
|
||||
desc = (MPI2_REPLY_DESCRIPTORS_UNION *)&tdesc;
|
||||
|
||||
flags = desc->Default.ReplyFlags &
|
||||
MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
|
||||
if ((flags == MPI2_RPY_DESCRIPT_FLAGS_UNUSED) ||
|
||||
@ -2604,7 +2616,8 @@ mpr_intr_locked(void *data)
|
||||
cm = &sc->commands[
|
||||
le16toh(desc->AddressReply.SMID)];
|
||||
KASSERT(cm->cm_state == MPR_CM_STATE_INQUEUE,
|
||||
("command not inqueue\n"));
|
||||
("command SMID %d not inqueue\n",
|
||||
desc->AddressReply.SMID));
|
||||
cm->cm_state = MPR_CM_STATE_BUSY;
|
||||
cm->cm_reply = reply;
|
||||
cm->cm_reply_data =
|
||||
@ -2630,9 +2643,6 @@ mpr_intr_locked(void *data)
|
||||
mpr_display_reply_info(sc,cm->cm_reply);
|
||||
mpr_complete_command(sc, cm);
|
||||
}
|
||||
|
||||
desc->Words.Low = 0xffffffff;
|
||||
desc->Words.High = 0xffffffff;
|
||||
}
|
||||
|
||||
if (pq != sc->replypostindex) {
|
||||
|
@ -2361,12 +2361,13 @@ void
|
||||
mps_intr_locked(void *data)
|
||||
{
|
||||
MPI2_REPLY_DESCRIPTORS_UNION *desc;
|
||||
struct mps_softc *sc;
|
||||
struct mps_command *cm = NULL;
|
||||
uint8_t flags;
|
||||
u_int pq;
|
||||
MPI2_DIAG_RELEASE_REPLY *rel_rep;
|
||||
mps_fw_diagnostic_buffer_t *pBuffer;
|
||||
struct mps_softc *sc;
|
||||
struct mps_command *cm = NULL;
|
||||
uint64_t tdesc;
|
||||
uint8_t flags;
|
||||
u_int pq;
|
||||
|
||||
sc = (struct mps_softc *)data;
|
||||
|
||||
@ -2378,6 +2379,17 @@ mps_intr_locked(void *data)
|
||||
for ( ;; ) {
|
||||
cm = NULL;
|
||||
desc = &sc->post_queue[sc->replypostindex];
|
||||
|
||||
/*
|
||||
* Copy and clear out the descriptor so that any reentry will
|
||||
* immediately know that this descriptor has already been
|
||||
* looked at. There is unfortunate casting magic because the
|
||||
* MPI API doesn't have a cardinal 64bit type.
|
||||
*/
|
||||
tdesc = 0xffffffffffffffff;
|
||||
tdesc = atomic_swap_64((uint64_t *)desc, tdesc);
|
||||
desc = (MPI2_REPLY_DESCRIPTORS_UNION *)&tdesc;
|
||||
|
||||
flags = desc->Default.ReplyFlags &
|
||||
MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
|
||||
if ((flags == MPI2_RPY_DESCRIPT_FLAGS_UNUSED)
|
||||
@ -2496,9 +2508,6 @@ mps_intr_locked(void *data)
|
||||
mps_display_reply_info(sc,cm->cm_reply);
|
||||
mps_complete_command(sc, cm);
|
||||
}
|
||||
|
||||
desc->Words.Low = 0xffffffff;
|
||||
desc->Words.High = 0xffffffff;
|
||||
}
|
||||
|
||||
if (pq != sc->replypostindex) {
|
||||
|
Loading…
Reference in New Issue
Block a user