summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCornelia Huck <cohuck@redhat.com>2019-01-31 07:53:14 -0500
committerMichael S. Tsirkin <mst@redhat.com>2019-03-06 11:19:57 -0500
commitab7a2375fb8e83f8744c34442f476fa5a9df5e35 (patch)
tree58698720fc0a7a79f4fdefaae195aabf57a83dba
parent971bedca26e037ee961e090c84c2640563836d3e (diff)
virtio: hint if callbacks surprisingly might sleep
A virtio transport is free to implement some of the callbacks in virtio_config_ops in a matter that they cannot be called from atomic context (e.g. virtio-ccw, which maps a lot of the callbacks to channel I/O, which is an inherently asynchronous mechanism). This can be very surprising for developers using the much more common virtio-pci transport, just to find out that things break when used on s390. The documentation for virtio_config_ops now contains a comment explaining this, but it makes sense to add a might_sleep() annotation to various wrapper functions in the virtio core to avoid surprises later. Note that annotations are NOT added to two classes of calls: - direct calls from device drivers (all current callers should be fine, however) - calls which clearly won't be made from atomic context (such as those ultimately coming in via the driver core) Signed-off-by: Cornelia Huck <cohuck@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
-rw-r--r--drivers/virtio/virtio.c2
-rw-r--r--include/linux/virtio_config.h13
2 files changed, 15 insertions, 0 deletions
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index 59e36ef4920f..98b30f54342c 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -161,6 +161,7 @@ EXPORT_SYMBOL_GPL(virtio_config_enable);
161 161
162void virtio_add_status(struct virtio_device *dev, unsigned int status) 162void virtio_add_status(struct virtio_device *dev, unsigned int status)
163{ 163{
164 might_sleep();
164 dev->config->set_status(dev, dev->config->get_status(dev) | status); 165 dev->config->set_status(dev, dev->config->get_status(dev) | status);
165} 166}
166EXPORT_SYMBOL_GPL(virtio_add_status); 167EXPORT_SYMBOL_GPL(virtio_add_status);
@@ -170,6 +171,7 @@ int virtio_finalize_features(struct virtio_device *dev)
170 int ret = dev->config->finalize_features(dev); 171 int ret = dev->config->finalize_features(dev);
171 unsigned status; 172 unsigned status;
172 173
174 might_sleep();
173 if (ret) 175 if (ret)
174 return ret; 176 return ret;
175 177
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
index 987b6491b946..bb4cc4910750 100644
--- a/include/linux/virtio_config.h
+++ b/include/linux/virtio_config.h
@@ -290,6 +290,7 @@ static inline __virtio64 cpu_to_virtio64(struct virtio_device *vdev, u64 val)
290/* Config space accessors. */ 290/* Config space accessors. */
291#define virtio_cread(vdev, structname, member, ptr) \ 291#define virtio_cread(vdev, structname, member, ptr) \
292 do { \ 292 do { \
293 might_sleep(); \
293 /* Must match the member's type, and be integer */ \ 294 /* Must match the member's type, and be integer */ \
294 if (!typecheck(typeof((((structname*)0)->member)), *(ptr))) \ 295 if (!typecheck(typeof((((structname*)0)->member)), *(ptr))) \
295 (*ptr) = 1; \ 296 (*ptr) = 1; \
@@ -319,6 +320,7 @@ static inline __virtio64 cpu_to_virtio64(struct virtio_device *vdev, u64 val)
319/* Config space accessors. */ 320/* Config space accessors. */
320#define virtio_cwrite(vdev, structname, member, ptr) \ 321#define virtio_cwrite(vdev, structname, member, ptr) \
321 do { \ 322 do { \
323 might_sleep(); \
322 /* Must match the member's type, and be integer */ \ 324 /* Must match the member's type, and be integer */ \
323 if (!typecheck(typeof((((structname*)0)->member)), *(ptr))) \ 325 if (!typecheck(typeof((((structname*)0)->member)), *(ptr))) \
324 BUG_ON((*ptr) == 1); \ 326 BUG_ON((*ptr) == 1); \
@@ -358,6 +360,7 @@ static inline void __virtio_cread_many(struct virtio_device *vdev,
358 vdev->config->generation(vdev) : 0; 360 vdev->config->generation(vdev) : 0;
359 int i; 361 int i;
360 362
363 might_sleep();
361 do { 364 do {
362 old = gen; 365 old = gen;
363 366
@@ -380,6 +383,8 @@ static inline void virtio_cread_bytes(struct virtio_device *vdev,
380static inline u8 virtio_cread8(struct virtio_device *vdev, unsigned int offset) 383static inline u8 virtio_cread8(struct virtio_device *vdev, unsigned int offset)
381{ 384{
382 u8 ret; 385 u8 ret;
386
387 might_sleep();
383 vdev->config->get(vdev, offset, &ret, sizeof(ret)); 388 vdev->config->get(vdev, offset, &ret, sizeof(ret));
384 return ret; 389 return ret;
385} 390}
@@ -387,6 +392,7 @@ static inline u8 virtio_cread8(struct virtio_device *vdev, unsigned int offset)
387static inline void virtio_cwrite8(struct virtio_device *vdev, 392static inline void virtio_cwrite8(struct virtio_device *vdev,
388 unsigned int offset, u8 val) 393 unsigned int offset, u8 val)
389{ 394{
395 might_sleep();
390 vdev->config->set(vdev, offset, &val, sizeof(val)); 396 vdev->config->set(vdev, offset, &val, sizeof(val));
391} 397}
392 398
@@ -394,6 +400,8 @@ static inline u16 virtio_cread16(struct virtio_device *vdev,
394 unsigned int offset) 400 unsigned int offset)
395{ 401{
396 u16 ret; 402 u16 ret;
403
404 might_sleep();
397 vdev->config->get(vdev, offset, &ret, sizeof(ret)); 405 vdev->config->get(vdev, offset, &ret, sizeof(ret));
398 return virtio16_to_cpu(vdev, (__force __virtio16)ret); 406 return virtio16_to_cpu(vdev, (__force __virtio16)ret);
399} 407}
@@ -401,6 +409,7 @@ static inline u16 virtio_cread16(struct virtio_device *vdev,
401static inline void virtio_cwrite16(struct virtio_device *vdev, 409static inline void virtio_cwrite16(struct virtio_device *vdev,
402 unsigned int offset, u16 val) 410 unsigned int offset, u16 val)
403{ 411{
412 might_sleep();
404 val = (__force u16)cpu_to_virtio16(vdev, val); 413 val = (__force u16)cpu_to_virtio16(vdev, val);
405 vdev->config->set(vdev, offset, &val, sizeof(val)); 414 vdev->config->set(vdev, offset, &val, sizeof(val));
406} 415}
@@ -409,6 +418,8 @@ static inline u32 virtio_cread32(struct virtio_device *vdev,
409 unsigned int offset) 418 unsigned int offset)
410{ 419{
411 u32 ret; 420 u32 ret;
421
422 might_sleep();
412 vdev->config->get(vdev, offset, &ret, sizeof(ret)); 423 vdev->config->get(vdev, offset, &ret, sizeof(ret));
413 return virtio32_to_cpu(vdev, (__force __virtio32)ret); 424 return virtio32_to_cpu(vdev, (__force __virtio32)ret);
414} 425}
@@ -416,6 +427,7 @@ static inline u32 virtio_cread32(struct virtio_device *vdev,
416static inline void virtio_cwrite32(struct virtio_device *vdev, 427static inline void virtio_cwrite32(struct virtio_device *vdev,
417 unsigned int offset, u32 val) 428 unsigned int offset, u32 val)
418{ 429{
430 might_sleep();
419 val = (__force u32)cpu_to_virtio32(vdev, val); 431 val = (__force u32)cpu_to_virtio32(vdev, val);
420 vdev->config->set(vdev, offset, &val, sizeof(val)); 432 vdev->config->set(vdev, offset, &val, sizeof(val));
421} 433}
@@ -431,6 +443,7 @@ static inline u64 virtio_cread64(struct virtio_device *vdev,
431static inline void virtio_cwrite64(struct virtio_device *vdev, 443static inline void virtio_cwrite64(struct virtio_device *vdev,
432 unsigned int offset, u64 val) 444 unsigned int offset, u64 val)
433{ 445{
446 might_sleep();
434 val = (__force u64)cpu_to_virtio64(vdev, val); 447 val = (__force u64)cpu_to_virtio64(vdev, val);
435 vdev->config->set(vdev, offset, &val, sizeof(val)); 448 vdev->config->set(vdev, offset, &val, sizeof(val));
436} 449}