瀏覽代碼

staging: unisys: visorchannel: Add peek function

According to unisys, the s_par hypervisor has a bug in which it never
triggers an interrupt.  That makes the visornic effectively a 2ms poll
loop.  In order to just have the rx thread shceduling a napi poll every
2ms, lets instead give it the chance to check the response queue for
data before we schedule.  This helper provides that functionality

Signed-off-by: Neil Horman <nhorman@redhat.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Neil Horman 10 年之前
父節點
當前提交
fdc792cd1b
共有 2 個文件被更改,包括 23 次插入0 次删除
  1. 2 0
      drivers/staging/unisys/include/visorbus.h
  2. 21 0
      drivers/staging/unisys/visorbus/visorchannel.c

+ 2 - 0
drivers/staging/unisys/include/visorbus.h

@@ -201,6 +201,8 @@ bool visorchannel_signalremove(struct visorchannel *channel, u32 queue,
 			       void *msg);
 			       void *msg);
 bool visorchannel_signalinsert(struct visorchannel *channel, u32 queue,
 bool visorchannel_signalinsert(struct visorchannel *channel, u32 queue,
 			       void *msg);
 			       void *msg);
+bool visorchannel_signalempty(struct visorchannel *channel, u32 queue);
+
 int visorchannel_signalqueue_slots_avail(struct visorchannel *channel,
 int visorchannel_signalqueue_slots_avail(struct visorchannel *channel,
 					 u32 queue);
 					 u32 queue);
 int visorchannel_signalqueue_max_slots(struct visorchannel *channel, u32 queue);
 int visorchannel_signalqueue_max_slots(struct visorchannel *channel, u32 queue);

+ 21 - 0
drivers/staging/unisys/visorbus/visorchannel.c

@@ -430,6 +430,27 @@ visorchannel_signalremove(struct visorchannel *channel, u32 queue, void *msg)
 }
 }
 EXPORT_SYMBOL_GPL(visorchannel_signalremove);
 EXPORT_SYMBOL_GPL(visorchannel_signalremove);
 
 
+bool
+visorchannel_signalempty(struct visorchannel *channel, u32 queue)
+{
+	unsigned long flags = 0;
+	struct signal_queue_header sig_hdr;
+	bool rc = false;
+
+	if (channel->needs_lock)
+		spin_lock_irqsave(&channel->remove_lock, flags);
+
+	if (!sig_read_header(channel, queue, &sig_hdr))
+		rc = true;
+	if (sig_hdr.head == sig_hdr.tail)
+		rc = true;
+	if (channel->needs_lock)
+		spin_unlock_irqrestore(&channel->remove_lock, flags);
+
+	return rc;
+}
+EXPORT_SYMBOL_GPL(visorchannel_signalempty);
+
 static bool
 static bool
 signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg)
 signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg)
 {
 {