Page MenuHomeFreeBSD

D8020.id20667.diff
No OneTemporary

D8020.id20667.diff

Index: sys/cam/cam.h
===================================================================
--- sys/cam/cam.h
+++ sys/cam/cam.h
@@ -92,8 +92,9 @@
u_int32_t generation;
int index;
#define CAM_UNQUEUED_INDEX -1
-#define CAM_ACTIVE_INDEX -2
-#define CAM_DONEQ_INDEX -3
+#define CAM_TRANSIENT_INDEX -2
+#define CAM_ACTIVE_INDEX -3
+#define CAM_DONEQ_INDEX -4
#define CAM_EXTRAQ_INDEX INT_MAX
} cam_pinfo;
Index: sys/cam/cam_queue.h
===================================================================
--- sys/cam/cam_queue.h
+++ sys/cam/cam_queue.h
@@ -136,7 +136,7 @@
* camq_remove: Remove and arbitrary entry from the queue maintaining
* queue order.
*/
-cam_pinfo *camq_remove(struct camq *queue, int index);
+cam_pinfo *camq_remove(struct camq *queue, int index, int new_index);
#define CAMQ_HEAD 1 /* Head of queue index */
/* Index the first element in the heap */
@@ -203,7 +203,8 @@
*/
if (queue->entries == queue->array_size &&
camq_resize(&ccbq->queue, queue->array_size * 2) != CAM_REQ_CMP) {
- old_ccb = (struct ccb_hdr *)camq_remove(queue, queue->entries);
+ old_ccb = (struct ccb_hdr *)camq_remove(queue, queue->entries,
+ CAM_TRANSIENT_INDEX);
TAILQ_INSERT_HEAD(&ccbq->queue_extra_head, old_ccb,
xpt_links.tqe);
old_ccb->pinfo.index = CAM_EXTRAQ_INDEX;
@@ -223,12 +224,12 @@
if (ccb->ccb_h.pinfo.index == CAM_EXTRAQ_INDEX) {
TAILQ_REMOVE(&ccbq->queue_extra_head, &ccb->ccb_h,
xpt_links.tqe);
- ccb->ccb_h.pinfo.index = CAM_UNQUEUED_INDEX;
+ ccb->ccb_h.pinfo.index = CAM_TRANSIENT_INDEX;
ccbq->queue_extra_entries--;
return;
}
- camq_remove(queue, ccb->ccb_h.pinfo.index);
+ camq_remove(queue, ccb->ccb_h.pinfo.index, CAM_TRANSIENT_INDEX);
/*
* If there are some CCBs on TAILQ, find the best one and move it
Index: sys/cam/cam_queue.c
===================================================================
--- sys/cam/cam_queue.c
+++ sys/cam/cam_queue.c
@@ -170,12 +170,19 @@
* Heap(1, num_elements) property and an index such that 1 <= index <=
* num_elements, remove that entry and restore the Heap(1, num_elements-1)
* property.
+ *
+ * Care should be taken to avoid glitches in the value of index because in some
+ * contexts it may be inspected by a thread that does not possess a contending
+ * lock. In particular, a temporary value of CAM_UNQUEUED_INDEX may be
+ * interpreted as "done" in some contexts.
*/
cam_pinfo *
-camq_remove(struct camq *queue, int index)
+camq_remove(struct camq *queue, int index, int new_index)
{
cam_pinfo *removed_entry;
+ KASSERT(new_index < 0, ("%s: bad new_index %d", __func__, new_index));
+
if (index == 0 || index > queue->entries)
return (NULL);
removed_entry = queue->queue_array[index];
@@ -184,7 +191,7 @@
queue->queue_array[index]->index = index;
heap_down(queue->queue_array, index, queue->entries - 1);
}
- removed_entry->index = CAM_UNQUEUED_INDEX;
+ removed_entry->index = new_index;
queue->entries--;
return (removed_entry);
}
Index: sys/cam/cam_xpt.c
===================================================================
--- sys/cam/cam_xpt.c
+++ sys/cam/cam_xpt.c
@@ -3257,7 +3257,8 @@
struct xpt_proto *proto;
device = (struct cam_ed *)camq_remove(&devq->send_queue,
- CAMQ_HEAD);
+ CAMQ_HEAD,
+ CAM_UNQUEUED_INDEX);
CAM_DEBUG_PRINT(CAM_DEBUG_XPT,
("running device %p\n", device));
@@ -4316,7 +4317,8 @@
freeze = (dev->ccbq.queue.qfrozen_cnt += count);
/* Remove frozen device from sendq. */
if (device_is_queued(dev))
- camq_remove(&devq->send_queue, dev->devq_entry.index);
+ camq_remove(&devq->send_queue, dev->devq_entry.index,
+ CAM_UNQUEUED_INDEX);
return (freeze);
}

File Metadata

Mime Type
text/plain
Expires
Sun, Jun 14, 10:16 AM (11 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33948451
Default Alt Text
D8020.id20667.diff (3 KB)

Event Timeline