qio: Add helpers to toggle state
authorBarret Rhoden <brho@cs.berkeley.edu>
Wed, 21 Sep 2016 18:12:50 +0000 (14:12 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Wed, 21 Sep 2016 21:28:01 +0000 (17:28 -0400)
I have a use case where I want to toggle Qmsg | Qcoalesce on at runtime,
specifically for using snoopy.  This is probably safe to do, though if you
have code that expects Qmsg, then suddenly it is turned off/on, it might
get confused by a short read.  So be careful.

With these two flags, I can turn a queue into "one non-zero block at a
time" mode.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/include/ns.h
kern/src/ns/qio.c

index 95fc42f..5ccd0de 100644 (file)
@@ -631,7 +631,7 @@ enum {
        Qmsg = (1 << 1),        /* message stream */
        Qclosed = (1 << 2),     /* queue has been closed/hungup */
        Qflow = (1 << 3),       /* producer flow controlled */
-       Qcoalesce = (1 << 4),   /* coallesce packets on read */
+       Qcoalesce = (1 << 4),   /* coalesce empty packets on read */
        Qkick = (1 << 5),       /* always call the kick routine after qwrite */
        Qdropoverflow = (1 << 6),       /* writes that would block will be dropped */
 };
@@ -833,6 +833,8 @@ int qisclosed(struct queue *);
 ssize_t qiwrite(struct queue *, void *, int);
 int qlen(struct queue *);
 void qdropoverflow(struct queue *, bool);
+void q_toggle_qmsg(struct queue *q, bool onoff);
+void q_toggle_qcoalesce(struct queue *q, bool onoff);
 struct queue *qopen(int unused_int, int, void (*)(void *), void *);
 ssize_t qpass(struct queue *, struct block *);
 ssize_t qpassnolim(struct queue *, struct block *);
index d229b3c..df53759 100644 (file)
@@ -1791,6 +1791,30 @@ void qdropoverflow(struct queue *q, bool onoff)
        spin_unlock_irqsave(&q->lock);
 }
 
+/* Be careful: this can affect concurrent reads/writes and code that might have
+ * built-in expectations of the q's type. */
+void q_toggle_qmsg(struct queue *q, bool onoff)
+{
+       spin_lock_irqsave(&q->lock);
+       if (onoff)
+               q->state |= Qmsg;
+       else
+               q->state &= ~Qmsg;
+       spin_unlock_irqsave(&q->lock);
+}
+
+/* Be careful: this can affect concurrent reads/writes and code that might have
+ * built-in expectations of the q's type. */
+void q_toggle_qcoalesce(struct queue *q, bool onoff)
+{
+       spin_lock_irqsave(&q->lock);
+       if (onoff)
+               q->state |= Qcoalesce;
+       else
+               q->state &= ~Qcoalesce;
+       spin_unlock_irqsave(&q->lock);
+}
+
 /*
  *  flush the output queue
  */