@@ -110,18 +110,16 @@ static void scmi_finalize_message(struct scmi_vio_channel *vioch,
110
110
if (vioch -> is_rx ) {
111
111
scmi_vio_feed_vq_rx (vioch , msg );
112
112
} else {
113
- unsigned long flags ;
114
-
115
- spin_lock_irqsave (& vioch -> lock , flags );
113
+ /* Here IRQs are assumed to be already disabled by the caller */
114
+ spin_lock (& vioch -> lock );
116
115
list_add (& msg -> list , & vioch -> free_list );
117
- spin_unlock_irqrestore (& vioch -> lock , flags );
116
+ spin_unlock (& vioch -> lock );
118
117
}
119
118
}
120
119
121
120
static void scmi_vio_complete_cb (struct virtqueue * vqueue )
122
121
{
123
122
unsigned long ready_flags ;
124
- unsigned long flags ;
125
123
unsigned int length ;
126
124
struct scmi_vio_channel * vioch ;
127
125
struct scmi_vio_msg * msg ;
@@ -140,7 +138,8 @@ static void scmi_vio_complete_cb(struct virtqueue *vqueue)
140
138
goto unlock_ready_out ;
141
139
}
142
140
143
- spin_lock_irqsave (& vioch -> lock , flags );
141
+ /* IRQs already disabled here no need to irqsave */
142
+ spin_lock (& vioch -> lock );
144
143
if (cb_enabled ) {
145
144
virtqueue_disable_cb (vqueue );
146
145
cb_enabled = false;
@@ -151,7 +150,7 @@ static void scmi_vio_complete_cb(struct virtqueue *vqueue)
151
150
goto unlock_out ;
152
151
cb_enabled = true;
153
152
}
154
- spin_unlock_irqrestore (& vioch -> lock , flags );
153
+ spin_unlock (& vioch -> lock );
155
154
156
155
if (msg ) {
157
156
msg -> rx_len = length ;
@@ -161,11 +160,18 @@ static void scmi_vio_complete_cb(struct virtqueue *vqueue)
161
160
scmi_finalize_message (vioch , msg );
162
161
}
163
162
163
+ /*
164
+ * Release ready_lock and re-enable IRQs between loop iterations
165
+ * to allow virtio_chan_free() to possibly kick in and set the
166
+ * flag vioch->ready to false even in between processing of
167
+ * messages, so as to force outstanding messages to be ignored
168
+ * when system is shutting down.
169
+ */
164
170
spin_unlock_irqrestore (& vioch -> ready_lock , ready_flags );
165
171
}
166
172
167
173
unlock_out :
168
- spin_unlock_irqrestore (& vioch -> lock , flags );
174
+ spin_unlock (& vioch -> lock );
169
175
unlock_ready_out :
170
176
spin_unlock_irqrestore (& vioch -> ready_lock , ready_flags );
171
177
}
@@ -435,6 +441,13 @@ static int scmi_vio_probe(struct virtio_device *vdev)
435
441
436
442
static void scmi_vio_remove (struct virtio_device * vdev )
437
443
{
444
+ /*
445
+ * Once we get here, virtio_chan_free() will have already been called by
446
+ * the SCMI core for any existing channel and, as a consequence, all the
447
+ * virtio channels will have been already marked NOT ready, causing any
448
+ * outstanding message on any vqueue to be ignored by complete_cb: now
449
+ * we can just stop processing buffers and destroy the vqueues.
450
+ */
438
451
vdev -> config -> reset (vdev );
439
452
vdev -> config -> del_vqs (vdev );
440
453
scmi_vdev = NULL ;
0 commit comments