.. | .. |
---|
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 |
---|