diff options
-rw-r--r-- | drivers/net/ethernet/intel/fm10k/fm10k_iov.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_iov.c b/drivers/net/ethernet/intel/fm10k/fm10k_iov.c index 0b37e197e300..5b08e6284a3c 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_iov.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_iov.c | |||
@@ -113,6 +113,13 @@ s32 fm10k_iov_mbx(struct fm10k_intfc *interface) | |||
113 | /* lock the mailbox for transmit and receive */ | 113 | /* lock the mailbox for transmit and receive */ |
114 | fm10k_mbx_lock(interface); | 114 | fm10k_mbx_lock(interface); |
115 | 115 | ||
116 | /* Most VF messages sent to the PF cause the PF to respond by | ||
117 | * requesting from the SM mailbox. This means that too many VF | ||
118 | * messages processed at once could cause a mailbox timeout on the PF. | ||
119 | * To prevent this, store a pointer to the next VF mbx to process. Use | ||
120 | * that as the start of the loop so that we don't starve whichever VF | ||
121 | * got ignored on the previous run. | ||
122 | */ | ||
116 | process_mbx: | 123 | process_mbx: |
117 | for (i = iov_data->next_vf_mbx ? : iov_data->num_vfs; i--;) { | 124 | for (i = iov_data->next_vf_mbx ? : iov_data->num_vfs; i--;) { |
118 | struct fm10k_vf_info *vf_info = &iov_data->vf_info[i]; | 125 | struct fm10k_vf_info *vf_info = &iov_data->vf_info[i]; |
@@ -137,6 +144,10 @@ process_mbx: | |||
137 | mbx->ops.process(hw, mbx); | 144 | mbx->ops.process(hw, mbx); |
138 | } | 145 | } |
139 | 146 | ||
147 | /* if we stopped processing mailboxes early, update next_vf_mbx. | ||
148 | * Otherwise, reset next_vf_mbx, and restart loop so that we process | ||
149 | * the remaining mailboxes we skipped at the start. | ||
150 | */ | ||
140 | if (i >= 0) { | 151 | if (i >= 0) { |
141 | iov_data->next_vf_mbx = i + 1; | 152 | iov_data->next_vf_mbx = i + 1; |
142 | } else if (iov_data->next_vf_mbx) { | 153 | } else if (iov_data->next_vf_mbx) { |