99#include "virtio_pmem.h"
1010#include "nd.h"
1111
12+ struct virtio_pmem_flush_work {
13+ struct work_struct work ;
14+ struct nd_region * nd_region ;
15+ struct bio * bio ;
16+ };
17+
18+ static void virtio_pmem_req_release (struct kref * kref )
19+ {
20+ struct virtio_pmem_request * req ;
21+
22+ req = container_of (kref , struct virtio_pmem_request , kref );
23+ kfree (req );
24+ }
25+
26+ static void virtio_pmem_signal_done (struct virtio_pmem_request * req )
27+ {
28+ /* Pairs with smp_load_acquire() in virtio_pmem_req_done(). */
29+ smp_store_release (& req -> done , true);
30+ wake_up (& req -> host_acked );
31+ }
32+
33+ static bool virtio_pmem_req_done (struct virtio_pmem_request * req )
34+ {
35+ /* Pairs with smp_store_release() in virtio_pmem_signal_done(). */
36+ return smp_load_acquire (& req -> done );
37+ }
38+
39+ static void virtio_pmem_complete_err (struct virtio_pmem_request * req )
40+ {
41+ req -> resp .ret = cpu_to_le32 (1 );
42+ virtio_pmem_signal_done (req );
43+ }
44+
45+ static void virtio_pmem_wake_one_waiter (struct virtio_pmem * vpmem )
46+ {
47+ struct virtio_pmem_request * req_buf ;
48+
49+ if (list_empty (& vpmem -> req_list ))
50+ return ;
51+
52+ req_buf = list_first_entry (& vpmem -> req_list ,
53+ struct virtio_pmem_request , list );
54+ list_del_init (& req_buf -> list );
55+ WRITE_ONCE (req_buf -> wq_buf_avail , true);
56+ wake_up (& req_buf -> wq_buf );
57+ }
58+
59+ static void virtio_pmem_wake_all_waiters (struct virtio_pmem * vpmem )
60+ {
61+ struct virtio_pmem_request * req , * tmp ;
62+
63+ list_for_each_entry_safe (req , tmp , & vpmem -> req_list , list ) {
64+ list_del_init (& req -> list );
65+ WRITE_ONCE (req -> wq_buf_avail , true);
66+ wake_up (& req -> wq_buf );
67+ }
68+ }
69+
70+ static void virtio_pmem_clear_inflight (struct virtio_pmem * vpmem ,
71+ struct virtio_pmem_request * req )
72+ {
73+ if (vpmem -> req_inflight == req )
74+ vpmem -> req_inflight = NULL ;
75+ }
76+
77+ static void virtio_pmem_wake_inflight (struct virtio_pmem * vpmem )
78+ {
79+ struct virtio_pmem_request * req = vpmem -> req_inflight ;
80+
81+ if (req )
82+ wake_up (& req -> host_acked );
83+ }
84+
85+ void virtio_pmem_mark_broken (struct virtio_pmem * vpmem )
86+ {
87+ if (!READ_ONCE (vpmem -> broken )) {
88+ WRITE_ONCE (vpmem -> broken , true);
89+ dev_err_once (& vpmem -> vdev -> dev , "virtqueue is broken\n" );
90+ }
91+
92+ virtio_pmem_wake_inflight (vpmem );
93+ virtio_pmem_wake_all_waiters (vpmem );
94+ }
95+ EXPORT_SYMBOL_GPL (virtio_pmem_mark_broken );
96+
97+ void virtio_pmem_drain (struct virtio_pmem * vpmem )
98+ {
99+ struct virtio_pmem_request * req ;
100+ unsigned int len ;
101+
102+ if (!vpmem -> req_vq )
103+ return ;
104+
105+ while ((req = virtqueue_get_buf (vpmem -> req_vq , & len )) != NULL ) {
106+ virtio_pmem_clear_inflight (vpmem , req );
107+ virtio_pmem_complete_err (req );
108+ kref_put (& req -> kref , virtio_pmem_req_release );
109+ }
110+
111+ while ((req = virtqueue_detach_unused_buf (vpmem -> req_vq )) != NULL ) {
112+ virtio_pmem_clear_inflight (vpmem , req );
113+ virtio_pmem_complete_err (req );
114+ kref_put (& req -> kref , virtio_pmem_req_release );
115+ }
116+ }
117+ EXPORT_SYMBOL_GPL (virtio_pmem_drain );
118+
12119 /* The interrupt handler */
13120void virtio_pmem_host_ack (struct virtqueue * vq )
14121{
15122 struct virtio_pmem * vpmem = vq -> vdev -> priv ;
16- struct virtio_pmem_request * req_data , * req_buf ;
123+ struct virtio_pmem_request * req_data ;
17124 unsigned long flags ;
18125 unsigned int len ;
19126
20127 spin_lock_irqsave (& vpmem -> pmem_lock , flags );
21128 while ((req_data = virtqueue_get_buf (vq , & len )) != NULL ) {
22- req_data -> done = true;
23- wake_up (& req_data -> host_acked );
24-
25- if (!list_empty (& vpmem -> req_list )) {
26- req_buf = list_first_entry (& vpmem -> req_list ,
27- struct virtio_pmem_request , list );
28- req_buf -> wq_buf_avail = true;
29- wake_up (& req_buf -> wq_buf );
30- list_del (& req_buf -> list );
31- }
129+ virtio_pmem_clear_inflight (vpmem , req_data );
130+ virtio_pmem_wake_one_waiter (vpmem );
131+ if (READ_ONCE (vpmem -> broken ))
132+ virtio_pmem_complete_err (req_data );
133+ else
134+ virtio_pmem_signal_done (req_data );
135+ kref_put (& req_data -> kref , virtio_pmem_req_release );
32136 }
33137 spin_unlock_irqrestore (& vpmem -> pmem_lock , flags );
34138}
@@ -55,11 +159,15 @@ static int virtio_pmem_flush(struct nd_region *nd_region)
55159 return - EIO ;
56160 }
57161
58- req_data = kmalloc_obj (* req_data );
162+ if (READ_ONCE (vpmem -> broken ))
163+ return - EIO ;
164+
165+ req_data = kmalloc_obj (* req_data , GFP_NOIO );
59166 if (!req_data )
60167 return - ENOMEM ;
61168
62- req_data -> done = false;
169+ kref_init (& req_data -> kref );
170+ WRITE_ONCE (req_data -> done , false);
63171 init_waitqueue_head (& req_data -> host_acked );
64172 init_waitqueue_head (& req_data -> wq_buf );
65173 INIT_LIST_HEAD (& req_data -> list );
@@ -70,67 +178,132 @@ static int virtio_pmem_flush(struct nd_region *nd_region)
70178 sgs [1 ] = & ret ;
71179
72180 spin_lock_irqsave (& vpmem -> pmem_lock , flags );
73- /*
74- * If virtqueue_add_sgs returns -ENOSPC then req_vq virtual
75- * queue does not have free descriptor. We add the request
76- * to req_list and wait for host_ack to wake us up when free
77- * slots are available.
78- */
79- while ((err = virtqueue_add_sgs (vpmem -> req_vq , sgs , 1 , 1 , req_data ,
80- GFP_ATOMIC )) == - ENOSPC ) {
81-
82- dev_info (& vdev -> dev , "failed to send command to virtio pmem device, no free slots in the virtqueue\n" );
83- req_data -> wq_buf_avail = false;
181+ /*
182+ * If virtqueue_add_sgs returns -ENOSPC then req_vq virtual
183+ * queue does not have free descriptor. We add the request
184+ * to req_list and wait for host_ack to wake us up when free
185+ * slots are available.
186+ */
187+ for (;;) {
188+ if (READ_ONCE (vpmem -> broken )) {
189+ err = - EIO ;
190+ break ;
191+ }
192+
193+ err = virtqueue_add_sgs (vpmem -> req_vq , sgs , 1 , 1 , req_data ,
194+ GFP_ATOMIC );
195+ if (!err ) {
196+ /*
197+ * Take the virtqueue reference while @pmem_lock is
198+ * held so completion cannot run concurrently.
199+ */
200+ kref_get (& req_data -> kref );
201+ vpmem -> req_inflight = req_data ;
202+ break ;
203+ }
204+
205+ if (err != - ENOSPC )
206+ break ;
207+
208+ dev_info_ratelimited (& vdev -> dev ,
209+ "failed to send command to virtio pmem device, no free slots in the virtqueue\n" );
210+ WRITE_ONCE (req_data -> wq_buf_avail , false);
84211 list_add_tail (& req_data -> list , & vpmem -> req_list );
85212 spin_unlock_irqrestore (& vpmem -> pmem_lock , flags );
86213
87214 /* A host response results in "host_ack" getting called */
88- wait_event (req_data -> wq_buf , req_data -> wq_buf_avail );
215+ wait_event (req_data -> wq_buf ,
216+ READ_ONCE (req_data -> wq_buf_avail ) ||
217+ READ_ONCE (vpmem -> broken ));
89218 spin_lock_irqsave (& vpmem -> pmem_lock , flags );
219+
220+ if (READ_ONCE (vpmem -> broken ))
221+ break ;
222+ }
223+
224+ if (READ_ONCE (vpmem -> broken ))
225+ err = - EIO ;
226+ if (err == - EIO || virtqueue_is_broken (vpmem -> req_vq ))
227+ virtio_pmem_mark_broken (vpmem );
228+
229+ err1 = true;
230+ if (!err && !READ_ONCE (vpmem -> broken )) {
231+ err1 = virtqueue_kick (vpmem -> req_vq );
232+ if (!err1 )
233+ virtio_pmem_mark_broken (vpmem );
90234 }
91- err1 = virtqueue_kick (vpmem -> req_vq );
92235 spin_unlock_irqrestore (& vpmem -> pmem_lock , flags );
93236 /*
94237 * virtqueue_add_sgs failed with error different than -ENOSPC, we can't
95238 * do anything about that.
96239 */
97- if (err || !err1 ) {
240+ if (READ_ONCE ( vpmem -> broken ) || err || !err1 ) {
98241 dev_info (& vdev -> dev , "failed to send command to virtio pmem device\n" );
99242 err = - EIO ;
100243 } else {
101244 /* A host response results in "host_ack" getting called */
102- wait_event (req_data -> host_acked , req_data -> done );
103- err = le32_to_cpu (req_data -> resp .ret );
245+ wait_event (req_data -> host_acked ,
246+ virtio_pmem_req_done (req_data ) ||
247+ READ_ONCE (vpmem -> broken ));
248+ if (virtio_pmem_req_done (req_data ))
249+ err = le32_to_cpu (req_data -> resp .ret );
250+ else
251+ err = - EIO ;
104252 }
105253
106- kfree ( req_data );
254+ kref_put ( & req_data -> kref , virtio_pmem_req_release );
107255 return err ;
108256};
109257
258+ static void virtio_pmem_flush_work (struct work_struct * work )
259+ {
260+ struct virtio_pmem_flush_work * flush ;
261+ int err ;
262+
263+ flush = container_of (work , struct virtio_pmem_flush_work , work );
264+ err = virtio_pmem_flush (flush -> nd_region );
265+ if (err > 0 )
266+ err = - EIO ;
267+ if (err )
268+ flush -> bio -> bi_status = errno_to_blk_status (err );
269+ bio_endio (flush -> bio );
270+ kfree (flush );
271+ }
272+
110273/* The asynchronous flush callback function */
111274int async_pmem_flush (struct nd_region * nd_region , struct bio * bio )
112275{
113- /*
114- * Create child bio for asynchronous flush and chain with
115- * parent bio. Otherwise directly call nd_region flush.
116- */
117- if (bio && bio -> bi_iter .bi_sector != -1 ) {
118- struct bio * child = bio_alloc (bio -> bi_bdev , 0 ,
119- REQ_OP_WRITE | REQ_PREFLUSH ,
120- GFP_ATOMIC );
276+ struct virtio_device * vdev = nd_region -> provider_data ;
277+ struct virtio_pmem * vpmem = vdev -> priv ;
278+ struct virtio_pmem_flush_work * flush ;
279+ unsigned long flags ;
280+ int err ;
121281
122- if (!child )
282+ if (bio && bio -> bi_iter .bi_sector != -1 ) {
283+ flush = kmalloc_obj (* flush , GFP_NOIO );
284+ if (!flush )
123285 return - ENOMEM ;
124- bio_clone_blkg_association (child , bio );
125- child -> bi_iter .bi_sector = -1 ;
126- bio_chain (child , bio );
127- submit_bio (child );
128- return 0 ;
286+
287+ INIT_WORK (& flush -> work , virtio_pmem_flush_work );
288+ flush -> nd_region = nd_region ;
289+ flush -> bio = bio ;
290+
291+ spin_lock_irqsave (& vpmem -> pmem_lock , flags );
292+ if (READ_ONCE (vpmem -> broken )) {
293+ spin_unlock_irqrestore (& vpmem -> pmem_lock , flags );
294+ kfree (flush );
295+ return - EIO ;
296+ }
297+ queue_work (vpmem -> flush_wq , & flush -> work );
298+ spin_unlock_irqrestore (& vpmem -> pmem_lock , flags );
299+ return NVDIMM_FLUSH_ASYNC ;
129300 }
130- if (virtio_pmem_flush (nd_region ))
301+
302+ err = virtio_pmem_flush (nd_region );
303+ if (err > 0 )
131304 return - EIO ;
132305
133- return 0 ;
306+ return err ;
134307};
135308EXPORT_SYMBOL_GPL (async_pmem_flush );
136309MODULE_DESCRIPTION ("Virtio Persistent Memory Driver" );
0 commit comments