ring_buffer.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. /*
  2. *
  3. * Copyright (c) 2009, Microsoft Corporation.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms and conditions of the GNU General Public License,
  7. * version 2, as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along with
  15. * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
  16. * Place - Suite 330, Boston, MA 02111-1307 USA.
  17. *
  18. * Authors:
  19. * Haiyang Zhang <haiyangz@microsoft.com>
  20. * Hank Janssen <hjanssen@microsoft.com>
  21. * K. Y. Srinivasan <kys@microsoft.com>
  22. *
  23. */
  24. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  25. #include <linux/kernel.h>
  26. #include <linux/mm.h>
  27. #include <linux/hyperv.h>
  28. #include "hyperv_vmbus.h"
  29. void hv_begin_read(struct hv_ring_buffer_info *rbi)
  30. {
  31. rbi->ring_buffer->interrupt_mask = 1;
  32. smp_mb();
  33. }
  34. u32 hv_end_read(struct hv_ring_buffer_info *rbi)
  35. {
  36. u32 read;
  37. u32 write;
  38. rbi->ring_buffer->interrupt_mask = 0;
  39. smp_mb();
  40. /*
  41. * Now check to see if the ring buffer is still empty.
  42. * If it is not, we raced and we need to process new
  43. * incoming messages.
  44. */
  45. hv_get_ringbuffer_availbytes(rbi, &read, &write);
  46. return read;
  47. }
  48. /*
  49. * When we write to the ring buffer, check if the host needs to
  50. * be signaled. Here is the details of this protocol:
  51. *
  52. * 1. The host guarantees that while it is draining the
  53. * ring buffer, it will set the interrupt_mask to
  54. * indicate it does not need to be interrupted when
  55. * new data is placed.
  56. *
  57. * 2. The host guarantees that it will completely drain
  58. * the ring buffer before exiting the read loop. Further,
  59. * once the ring buffer is empty, it will clear the
  60. * interrupt_mask and re-check to see if new data has
  61. * arrived.
  62. */
  63. static bool hv_need_to_signal(u32 old_write, struct hv_ring_buffer_info *rbi)
  64. {
  65. if (rbi->ring_buffer->interrupt_mask)
  66. return false;
  67. /*
  68. * This is the only case we need to signal when the
  69. * ring transitions from being empty to non-empty.
  70. */
  71. if (old_write == rbi->ring_buffer->read_index)
  72. return true;
  73. return false;
  74. }
  75. /*
  76. * hv_get_next_write_location()
  77. *
  78. * Get the next write location for the specified ring buffer
  79. *
  80. */
  81. static inline u32
  82. hv_get_next_write_location(struct hv_ring_buffer_info *ring_info)
  83. {
  84. u32 next = ring_info->ring_buffer->write_index;
  85. return next;
  86. }
  87. /*
  88. * hv_set_next_write_location()
  89. *
  90. * Set the next write location for the specified ring buffer
  91. *
  92. */
  93. static inline void
  94. hv_set_next_write_location(struct hv_ring_buffer_info *ring_info,
  95. u32 next_write_location)
  96. {
  97. ring_info->ring_buffer->write_index = next_write_location;
  98. }
  99. /*
  100. * hv_get_next_read_location()
  101. *
  102. * Get the next read location for the specified ring buffer
  103. */
  104. static inline u32
  105. hv_get_next_read_location(struct hv_ring_buffer_info *ring_info)
  106. {
  107. u32 next = ring_info->ring_buffer->read_index;
  108. return next;
  109. }
  110. /*
  111. * hv_get_next_readlocation_withoffset()
  112. *
  113. * Get the next read location + offset for the specified ring buffer.
  114. * This allows the caller to skip
  115. */
  116. static inline u32
  117. hv_get_next_readlocation_withoffset(struct hv_ring_buffer_info *ring_info,
  118. u32 offset)
  119. {
  120. u32 next = ring_info->ring_buffer->read_index;
  121. next += offset;
  122. next %= ring_info->ring_datasize;
  123. return next;
  124. }
  125. /*
  126. *
  127. * hv_set_next_read_location()
  128. *
  129. * Set the next read location for the specified ring buffer
  130. *
  131. */
  132. static inline void
  133. hv_set_next_read_location(struct hv_ring_buffer_info *ring_info,
  134. u32 next_read_location)
  135. {
  136. ring_info->ring_buffer->read_index = next_read_location;
  137. }
  138. /*
  139. *
  140. * hv_get_ring_buffer()
  141. *
  142. * Get the start of the ring buffer
  143. */
  144. static inline void *
  145. hv_get_ring_buffer(struct hv_ring_buffer_info *ring_info)
  146. {
  147. return (void *)ring_info->ring_buffer->buffer;
  148. }
  149. /*
  150. *
  151. * hv_get_ring_buffersize()
  152. *
  153. * Get the size of the ring buffer
  154. */
  155. static inline u32
  156. hv_get_ring_buffersize(struct hv_ring_buffer_info *ring_info)
  157. {
  158. return ring_info->ring_datasize;
  159. }
  160. /*
  161. *
  162. * hv_get_ring_bufferindices()
  163. *
  164. * Get the read and write indices as u64 of the specified ring buffer
  165. *
  166. */
  167. static inline u64
  168. hv_get_ring_bufferindices(struct hv_ring_buffer_info *ring_info)
  169. {
  170. return (u64)ring_info->ring_buffer->write_index << 32;
  171. }
  172. /*
  173. *
  174. * hv_copyfrom_ringbuffer()
  175. *
  176. * Helper routine to copy to source from ring buffer.
  177. * Assume there is enough room. Handles wrap-around in src case only!!
  178. *
  179. */
  180. static u32 hv_copyfrom_ringbuffer(
  181. struct hv_ring_buffer_info *ring_info,
  182. void *dest,
  183. u32 destlen,
  184. u32 start_read_offset)
  185. {
  186. void *ring_buffer = hv_get_ring_buffer(ring_info);
  187. u32 ring_buffer_size = hv_get_ring_buffersize(ring_info);
  188. u32 frag_len;
  189. /* wrap-around detected at the src */
  190. if (destlen > ring_buffer_size - start_read_offset) {
  191. frag_len = ring_buffer_size - start_read_offset;
  192. memcpy(dest, ring_buffer + start_read_offset, frag_len);
  193. memcpy(dest + frag_len, ring_buffer, destlen - frag_len);
  194. } else
  195. memcpy(dest, ring_buffer + start_read_offset, destlen);
  196. start_read_offset += destlen;
  197. start_read_offset %= ring_buffer_size;
  198. return start_read_offset;
  199. }
  200. /*
  201. *
  202. * hv_copyto_ringbuffer()
  203. *
  204. * Helper routine to copy from source to ring buffer.
  205. * Assume there is enough room. Handles wrap-around in dest case only!!
  206. *
  207. */
  208. static u32 hv_copyto_ringbuffer(
  209. struct hv_ring_buffer_info *ring_info,
  210. u32 start_write_offset,
  211. void *src,
  212. u32 srclen)
  213. {
  214. void *ring_buffer = hv_get_ring_buffer(ring_info);
  215. u32 ring_buffer_size = hv_get_ring_buffersize(ring_info);
  216. u32 frag_len;
  217. /* wrap-around detected! */
  218. if (srclen > ring_buffer_size - start_write_offset) {
  219. frag_len = ring_buffer_size - start_write_offset;
  220. memcpy(ring_buffer + start_write_offset, src, frag_len);
  221. memcpy(ring_buffer, src + frag_len, srclen - frag_len);
  222. } else
  223. memcpy(ring_buffer + start_write_offset, src, srclen);
  224. start_write_offset += srclen;
  225. start_write_offset %= ring_buffer_size;
  226. return start_write_offset;
  227. }
  228. /*
  229. *
  230. * hv_ringbuffer_get_debuginfo()
  231. *
  232. * Get various debug metrics for the specified ring buffer
  233. *
  234. */
  235. void hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
  236. struct hv_ring_buffer_debug_info *debug_info)
  237. {
  238. u32 bytes_avail_towrite;
  239. u32 bytes_avail_toread;
  240. if (ring_info->ring_buffer) {
  241. hv_get_ringbuffer_availbytes(ring_info,
  242. &bytes_avail_toread,
  243. &bytes_avail_towrite);
  244. debug_info->bytes_avail_toread = bytes_avail_toread;
  245. debug_info->bytes_avail_towrite = bytes_avail_towrite;
  246. debug_info->current_read_index =
  247. ring_info->ring_buffer->read_index;
  248. debug_info->current_write_index =
  249. ring_info->ring_buffer->write_index;
  250. debug_info->current_interrupt_mask =
  251. ring_info->ring_buffer->interrupt_mask;
  252. }
  253. }
  254. /*
  255. *
  256. * hv_get_ringbuffer_interrupt_mask()
  257. *
  258. * Get the interrupt mask for the specified ring buffer
  259. *
  260. */
  261. u32 hv_get_ringbuffer_interrupt_mask(struct hv_ring_buffer_info *rbi)
  262. {
  263. return rbi->ring_buffer->interrupt_mask;
  264. }
  265. /*
  266. *
  267. * hv_ringbuffer_init()
  268. *
  269. *Initialize the ring buffer
  270. *
  271. */
  272. int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info,
  273. void *buffer, u32 buflen)
  274. {
  275. if (sizeof(struct hv_ring_buffer) != PAGE_SIZE)
  276. return -EINVAL;
  277. memset(ring_info, 0, sizeof(struct hv_ring_buffer_info));
  278. ring_info->ring_buffer = (struct hv_ring_buffer *)buffer;
  279. ring_info->ring_buffer->read_index =
  280. ring_info->ring_buffer->write_index = 0;
  281. ring_info->ring_size = buflen;
  282. ring_info->ring_datasize = buflen - sizeof(struct hv_ring_buffer);
  283. spin_lock_init(&ring_info->ring_lock);
  284. return 0;
  285. }
  286. /*
  287. *
  288. * hv_ringbuffer_cleanup()
  289. *
  290. * Cleanup the ring buffer
  291. *
  292. */
  293. void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info)
  294. {
  295. }
  296. /*
  297. *
  298. * hv_ringbuffer_write()
  299. *
  300. * Write to the ring buffer
  301. *
  302. */
  303. int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info,
  304. struct scatterlist *sglist, u32 sgcount, bool *signal)
  305. {
  306. int i = 0;
  307. u32 bytes_avail_towrite;
  308. u32 bytes_avail_toread;
  309. u32 totalbytes_towrite = 0;
  310. struct scatterlist *sg;
  311. u32 next_write_location;
  312. u32 old_write;
  313. u64 prev_indices = 0;
  314. unsigned long flags;
  315. for_each_sg(sglist, sg, sgcount, i)
  316. {
  317. totalbytes_towrite += sg->length;
  318. }
  319. totalbytes_towrite += sizeof(u64);
  320. spin_lock_irqsave(&outring_info->ring_lock, flags);
  321. hv_get_ringbuffer_availbytes(outring_info,
  322. &bytes_avail_toread,
  323. &bytes_avail_towrite);
  324. /* If there is only room for the packet, assume it is full. */
  325. /* Otherwise, the next time around, we think the ring buffer */
  326. /* is empty since the read index == write index */
  327. if (bytes_avail_towrite <= totalbytes_towrite) {
  328. spin_unlock_irqrestore(&outring_info->ring_lock, flags);
  329. return -EAGAIN;
  330. }
  331. /* Write to the ring buffer */
  332. next_write_location = hv_get_next_write_location(outring_info);
  333. old_write = next_write_location;
  334. for_each_sg(sglist, sg, sgcount, i)
  335. {
  336. next_write_location = hv_copyto_ringbuffer(outring_info,
  337. next_write_location,
  338. sg_virt(sg),
  339. sg->length);
  340. }
  341. /* Set previous packet start */
  342. prev_indices = hv_get_ring_bufferindices(outring_info);
  343. next_write_location = hv_copyto_ringbuffer(outring_info,
  344. next_write_location,
  345. &prev_indices,
  346. sizeof(u64));
  347. /* Issue a full memory barrier before updating the write index */
  348. smp_mb();
  349. /* Now, update the write location */
  350. hv_set_next_write_location(outring_info, next_write_location);
  351. spin_unlock_irqrestore(&outring_info->ring_lock, flags);
  352. *signal = hv_need_to_signal(old_write, outring_info);
  353. return 0;
  354. }
  355. /*
  356. *
  357. * hv_ringbuffer_peek()
  358. *
  359. * Read without advancing the read index
  360. *
  361. */
  362. int hv_ringbuffer_peek(struct hv_ring_buffer_info *Inring_info,
  363. void *Buffer, u32 buflen)
  364. {
  365. u32 bytes_avail_towrite;
  366. u32 bytes_avail_toread;
  367. u32 next_read_location = 0;
  368. unsigned long flags;
  369. spin_lock_irqsave(&Inring_info->ring_lock, flags);
  370. hv_get_ringbuffer_availbytes(Inring_info,
  371. &bytes_avail_toread,
  372. &bytes_avail_towrite);
  373. /* Make sure there is something to read */
  374. if (bytes_avail_toread < buflen) {
  375. spin_unlock_irqrestore(&Inring_info->ring_lock, flags);
  376. return -EAGAIN;
  377. }
  378. /* Convert to byte offset */
  379. next_read_location = hv_get_next_read_location(Inring_info);
  380. next_read_location = hv_copyfrom_ringbuffer(Inring_info,
  381. Buffer,
  382. buflen,
  383. next_read_location);
  384. spin_unlock_irqrestore(&Inring_info->ring_lock, flags);
  385. return 0;
  386. }
  387. /*
  388. *
  389. * hv_ringbuffer_read()
  390. *
  391. * Read and advance the read index
  392. *
  393. */
  394. int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer,
  395. u32 buflen, u32 offset)
  396. {
  397. u32 bytes_avail_towrite;
  398. u32 bytes_avail_toread;
  399. u32 next_read_location = 0;
  400. u64 prev_indices = 0;
  401. unsigned long flags;
  402. if (buflen <= 0)
  403. return -EINVAL;
  404. spin_lock_irqsave(&inring_info->ring_lock, flags);
  405. hv_get_ringbuffer_availbytes(inring_info,
  406. &bytes_avail_toread,
  407. &bytes_avail_towrite);
  408. /* Make sure there is something to read */
  409. if (bytes_avail_toread < buflen) {
  410. spin_unlock_irqrestore(&inring_info->ring_lock, flags);
  411. return -EAGAIN;
  412. }
  413. next_read_location =
  414. hv_get_next_readlocation_withoffset(inring_info, offset);
  415. next_read_location = hv_copyfrom_ringbuffer(inring_info,
  416. buffer,
  417. buflen,
  418. next_read_location);
  419. next_read_location = hv_copyfrom_ringbuffer(inring_info,
  420. &prev_indices,
  421. sizeof(u64),
  422. next_read_location);
  423. /* Make sure all reads are done before we update the read index since */
  424. /* the writer may start writing to the read area once the read index */
  425. /*is updated */
  426. smp_mb();
  427. /* Update the read index */
  428. hv_set_next_read_location(inring_info, next_read_location);
  429. spin_unlock_irqrestore(&inring_info->ring_lock, flags);
  430. return 0;
  431. }