From 1451f414639465995dfc1f820aa1a64723cbd662 Mon Sep 17 00:00:00 2001 From: Frank Haverkamp Date: Wed, 10 Sep 2014 16:37:53 +0200 Subject: GenWQE: Support blocking when DDCB queue is busy When the GenWQE hardware queue was busy, the driver returned simply -EBUSY. This caused polling by applications which increased the load on the already busy system. This change implements the possiblity to sleep on a waitqueue instead when the DDCB queue is busy. The requestor is woken up when there is free space on the queue again. The old way to get -EBUSY is still available if the device is openend with O_NONBLOCKING. The default is now blocking behavior. Signed-off-by: Frank Haverkamp Signed-off-by: Greg Kroah-Hartman --- drivers/misc/genwqe/card_base.h | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'drivers/misc/genwqe/card_base.h') diff --git a/drivers/misc/genwqe/card_base.h b/drivers/misc/genwqe/card_base.h index b622d204b72b..c64d7cad1085 100644 --- a/drivers/misc/genwqe/card_base.h +++ b/drivers/misc/genwqe/card_base.h @@ -201,7 +201,8 @@ static inline void genwqe_mapping_init(struct dma_mapping *m, * @ddcb_seq: Sequence number of last DDCB * @ddcbs_in_flight: Currently enqueued DDCBs * @ddcbs_completed: Number of already completed DDCBs - * @busy: Number of -EBUSY returns + * @return_on_busy: Number of -EBUSY returns on full queue + * @wait_on_busy: Number of waits on full queue * @ddcb_daddr: DMA address of first DDCB in the queue * @ddcb_vaddr: Kernel virtual address of first DDCB in the queue * @ddcb_req: Associated requests (one per DDCB) @@ -218,7 +219,8 @@ struct ddcb_queue { unsigned int ddcbs_in_flight; /* number of ddcbs in processing */ unsigned int ddcbs_completed; unsigned int ddcbs_max_in_flight; - unsigned int busy; /* how many times -EBUSY? */ + unsigned int return_on_busy; /* how many times -EBUSY? */ + unsigned int wait_on_busy; dma_addr_t ddcb_daddr; /* DMA address */ struct ddcb *ddcb_vaddr; /* kernel virtual addr for DDCBs */ @@ -226,7 +228,7 @@ struct ddcb_queue { wait_queue_head_t *ddcb_waitqs; /* waitqueue per ddcb */ spinlock_t ddcb_lock; /* exclusive access to queue */ - wait_queue_head_t ddcb_waitq; /* wait for ddcb processing */ + wait_queue_head_t busy_waitq; /* wait for ddcb processing */ /* registers or the respective queue to be used */ u32 IO_QUEUE_CONFIG; @@ -508,7 +510,7 @@ static inline bool dma_mapping_used(struct dma_mapping *m) * buildup and teardown. */ int __genwqe_execute_ddcb(struct genwqe_dev *cd, - struct genwqe_ddcb_cmd *cmd); + struct genwqe_ddcb_cmd *cmd, unsigned int f_flags); /** * __genwqe_execute_raw_ddcb() - Execute DDCB request without addr translation @@ -520,9 +522,12 @@ int __genwqe_execute_ddcb(struct genwqe_dev *cd, * modification. */ int __genwqe_execute_raw_ddcb(struct genwqe_dev *cd, - struct genwqe_ddcb_cmd *cmd); + struct genwqe_ddcb_cmd *cmd, + unsigned int f_flags); +int __genwqe_enqueue_ddcb(struct genwqe_dev *cd, + struct ddcb_requ *req, + unsigned int f_flags); -int __genwqe_enqueue_ddcb(struct genwqe_dev *cd, struct ddcb_requ *req); int __genwqe_wait_ddcb(struct genwqe_dev *cd, struct ddcb_requ *req); int __genwqe_purge_ddcb(struct genwqe_dev *cd, struct ddcb_requ *req); -- cgit v1.2.3