| .. | .. |
|---|
| 39 | 39 | /** Tasklet structures for this device. */ |
|---|
| 40 | 40 | struct tasklet_struct droq_tasklet; |
|---|
| 41 | 41 | unsigned long napi_mask; |
|---|
| 42 | + struct octeon_device *dev; |
|---|
| 42 | 43 | }; |
|---|
| 43 | 44 | |
|---|
| 44 | 45 | /** This structure is used by NIC driver to store information required |
|---|
| .. | .. |
|---|
| 70 | 71 | void octeon_report_tx_completion_to_bql(void *txq, unsigned int pkts_compl, |
|---|
| 71 | 72 | unsigned int bytes_compl); |
|---|
| 72 | 73 | void octeon_pf_changed_vf_macaddr(struct octeon_device *oct, u8 *mac); |
|---|
| 74 | + |
|---|
| 75 | +void octeon_schedule_rxq_oom_work(struct octeon_device *oct, |
|---|
| 76 | + struct octeon_droq *droq); |
|---|
| 77 | + |
|---|
| 73 | 78 | /** Swap 8B blocks */ |
|---|
| 74 | 79 | static inline void octeon_swap_8B_data(u64 *data, u32 blocks) |
|---|
| 75 | 80 | { |
|---|
| .. | .. |
|---|
| 146 | 151 | return 1; |
|---|
| 147 | 152 | } |
|---|
| 148 | 153 | |
|---|
| 154 | +/* input parameter: |
|---|
| 155 | + * sc: pointer to a soft request |
|---|
| 156 | + * timeout: milli sec which an application wants to wait for the |
|---|
| 157 | + response of the request. |
|---|
| 158 | + * 0: the request will wait until its response gets back |
|---|
| 159 | + * from the firmware within LIO_SC_MAX_TMO_MS milli sec. |
|---|
| 160 | + * It the response does not return within |
|---|
| 161 | + * LIO_SC_MAX_TMO_MS milli sec, lio_process_ordered_list() |
|---|
| 162 | + * will move the request to zombie response list. |
|---|
| 163 | + * |
|---|
| 164 | + * return value: |
|---|
| 165 | + * 0: got the response from firmware for the sc request. |
|---|
| 166 | + * errno -EINTR: user abort the command. |
|---|
| 167 | + * errno -ETIME: user spefified timeout value has been expired. |
|---|
| 168 | + * errno -EBUSY: the response of the request does not return in |
|---|
| 169 | + * resonable time (LIO_SC_MAX_TMO_MS). |
|---|
| 170 | + * the sc wll be move to zombie response list by |
|---|
| 171 | + * lio_process_ordered_list() |
|---|
| 172 | + * |
|---|
| 173 | + * A request with non-zero return value, the sc->caller_is_done |
|---|
| 174 | + * will be marked 1. |
|---|
| 175 | + * When getting a request with zero return value, the requestor |
|---|
| 176 | + * should mark sc->caller_is_done with 1 after examing the |
|---|
| 177 | + * response of sc. |
|---|
| 178 | + * lio_process_ordered_list() will free the soft command on behalf |
|---|
| 179 | + * of the soft command requestor. |
|---|
| 180 | + * This is to fix the possible race condition of both timeout process |
|---|
| 181 | + * and lio_process_ordered_list()/callback function to free a |
|---|
| 182 | + * sc strucutre. |
|---|
| 183 | + */ |
|---|
| 149 | 184 | static inline int |
|---|
| 150 | | -sleep_cond(wait_queue_head_t *wait_queue, int *condition) |
|---|
| 185 | +wait_for_sc_completion_timeout(struct octeon_device *oct_dev, |
|---|
| 186 | + struct octeon_soft_command *sc, |
|---|
| 187 | + unsigned long timeout) |
|---|
| 151 | 188 | { |
|---|
| 152 | 189 | int errno = 0; |
|---|
| 153 | | - wait_queue_entry_t we; |
|---|
| 190 | + long timeout_jiff; |
|---|
| 154 | 191 | |
|---|
| 155 | | - init_waitqueue_entry(&we, current); |
|---|
| 156 | | - add_wait_queue(wait_queue, &we); |
|---|
| 157 | | - while (!(READ_ONCE(*condition))) { |
|---|
| 158 | | - set_current_state(TASK_INTERRUPTIBLE); |
|---|
| 159 | | - if (signal_pending(current)) { |
|---|
| 160 | | - errno = -EINTR; |
|---|
| 161 | | - goto out; |
|---|
| 162 | | - } |
|---|
| 163 | | - schedule(); |
|---|
| 192 | + if (timeout) |
|---|
| 193 | + timeout_jiff = msecs_to_jiffies(timeout); |
|---|
| 194 | + else |
|---|
| 195 | + timeout_jiff = MAX_SCHEDULE_TIMEOUT; |
|---|
| 196 | + |
|---|
| 197 | + timeout_jiff = |
|---|
| 198 | + wait_for_completion_interruptible_timeout(&sc->complete, |
|---|
| 199 | + timeout_jiff); |
|---|
| 200 | + if (timeout_jiff == 0) { |
|---|
| 201 | + dev_err(&oct_dev->pci_dev->dev, "%s: sc is timeout\n", |
|---|
| 202 | + __func__); |
|---|
| 203 | + WRITE_ONCE(sc->caller_is_done, true); |
|---|
| 204 | + errno = -ETIME; |
|---|
| 205 | + } else if (timeout_jiff == -ERESTARTSYS) { |
|---|
| 206 | + dev_err(&oct_dev->pci_dev->dev, "%s: sc is interrupted\n", |
|---|
| 207 | + __func__); |
|---|
| 208 | + WRITE_ONCE(sc->caller_is_done, true); |
|---|
| 209 | + errno = -EINTR; |
|---|
| 210 | + } else if (sc->sc_status == OCTEON_REQUEST_TIMEOUT) { |
|---|
| 211 | + dev_err(&oct_dev->pci_dev->dev, "%s: sc has fatal timeout\n", |
|---|
| 212 | + __func__); |
|---|
| 213 | + WRITE_ONCE(sc->caller_is_done, true); |
|---|
| 214 | + errno = -EBUSY; |
|---|
| 164 | 215 | } |
|---|
| 165 | | -out: |
|---|
| 166 | | - set_current_state(TASK_RUNNING); |
|---|
| 167 | | - remove_wait_queue(wait_queue, &we); |
|---|
| 216 | + |
|---|
| 168 | 217 | return errno; |
|---|
| 169 | | -} |
|---|
| 170 | | - |
|---|
| 171 | | -/* Gives up the CPU for a timeout period. |
|---|
| 172 | | - * Check that the condition is not true before we go to sleep for a |
|---|
| 173 | | - * timeout period. |
|---|
| 174 | | - */ |
|---|
| 175 | | -static inline void |
|---|
| 176 | | -sleep_timeout_cond(wait_queue_head_t *wait_queue, |
|---|
| 177 | | - int *condition, |
|---|
| 178 | | - int timeout) |
|---|
| 179 | | -{ |
|---|
| 180 | | - wait_queue_entry_t we; |
|---|
| 181 | | - |
|---|
| 182 | | - init_waitqueue_entry(&we, current); |
|---|
| 183 | | - add_wait_queue(wait_queue, &we); |
|---|
| 184 | | - set_current_state(TASK_INTERRUPTIBLE); |
|---|
| 185 | | - if (!(*condition)) |
|---|
| 186 | | - schedule_timeout(timeout); |
|---|
| 187 | | - set_current_state(TASK_RUNNING); |
|---|
| 188 | | - remove_wait_queue(wait_queue, &we); |
|---|
| 189 | 218 | } |
|---|
| 190 | 219 | |
|---|
| 191 | 220 | #ifndef ROUNDUP4 |
|---|