Lines 66-71
__FBSDID("$FreeBSD$");
Link Here
|
66 |
#include <dev/virtio/scsi/virtio_scsi.h> |
66 |
#include <dev/virtio/scsi/virtio_scsi.h> |
67 |
#include <dev/virtio/scsi/virtio_scsivar.h> |
67 |
#include <dev/virtio/scsi/virtio_scsivar.h> |
68 |
|
68 |
|
|
|
69 |
#include <sys/types.h> |
70 |
#include <machine/atomic.h> |
71 |
|
69 |
#include "virtio_if.h" |
72 |
#include "virtio_if.h" |
70 |
|
73 |
|
71 |
static int vtscsi_modevent(module_t, int, void *); |
74 |
static int vtscsi_modevent(module_t, int, void *); |
Lines 1629-1634
vtscsi_set_request_lun(struct ccb_hdr *ccbh, uint8_t lun[])
Link Here
|
1629 |
lun[3] = ccbh->target_lun & 0xFF; |
1632 |
lun[3] = ccbh->target_lun & 0xFF; |
1630 |
} |
1633 |
} |
1631 |
|
1634 |
|
|
|
1635 |
static uint32_t counter = 0; |
1636 |
|
1632 |
static void |
1637 |
static void |
1633 |
vtscsi_init_scsi_cmd_req(struct vtscsi_softc *sc, struct ccb_scsiio *csio, |
1638 |
vtscsi_init_scsi_cmd_req(struct vtscsi_softc *sc, struct ccb_scsiio *csio, |
1634 |
struct virtio_scsi_cmd_req *cmd_req) |
1639 |
struct virtio_scsi_cmd_req *cmd_req) |
Lines 1650-1657
vtscsi_init_scsi_cmd_req(struct vtscsi_softc *sc, struct ccb_scsiio *csio,
Link Here
|
1650 |
break; |
1655 |
break; |
1651 |
} |
1656 |
} |
1652 |
|
1657 |
|
|
|
1658 |
// This code used to use the csio pointer as tag, but |
1659 |
// CTL truncates the tag to 32 bit which resulted in |
1660 |
// overlapping tags under load. Cargo cult the iSCSI |
1661 |
// tag handling. |
1662 |
// The iSCSI code assumes that operations won't be pending |
1663 |
// long enough to still to witness the 32 bit counter |
1664 |
// wrapping. The maximum value was reserved. |
1665 |
// The reservation could be an iSCSI only special case, |
1666 |
// but it shouldn't hurt performance to increment twice |
1667 |
// once every 2**32 commands. |
1668 |
// |
1669 |
// As I'm just hacking on this code without a sufficient |
1670 |
// understanding of its threading and locking I used an |
1671 |
// attomic fetchadd to increment the tag counter. |
1672 |
// The fetchadd operation is an atomic *post*-increment |
1673 |
// aka it returns the old tag value. |
1674 |
// |
1675 |
// TODO: Have this reviewed by someone with an understand of the |
1676 |
// SCSI specifications, VirtIO, and CAM. |
1677 |
// |
1678 |
// Questions: |
1679 |
// * The old code used the csio pointer as tag. Are there places |
1680 |
// expecting to map a tag back to the csio pointer? |
1681 |
// (Shouldn't have worked on 64 bit systems anyway). |
1682 |
// |
1683 |
// * Does the tag have to be stable for csio's lifetime e.g. |
1684 |
// during retries? |
1685 |
// |
1686 |
// Observations: |
1687 |
// * This change alone didn't prevent the (0x4D, 0xNN) |
1688 |
// overlapping tag. |
1689 |
uintptr_t tag; |
1690 |
do { |
1691 |
tag = atomic_fetchadd_32(&counter, 1); |
1692 |
} while ( __builtin_expect(tag == UINT32_MAX, false) ); |
1693 |
|
1653 |
vtscsi_set_request_lun(&csio->ccb_h, cmd_req->lun); |
1694 |
vtscsi_set_request_lun(&csio->ccb_h, cmd_req->lun); |
1654 |
cmd_req->tag = vtscsi_gtoh64(sc, (uintptr_t) csio); |
1695 |
cmd_req->tag = vtscsi_gtoh64(sc, tag); |
1655 |
cmd_req->task_attr = attr; |
1696 |
cmd_req->task_attr = attr; |
1656 |
|
1697 |
|
1657 |
memcpy(cmd_req->cdb, |
1698 |
memcpy(cmd_req->cdb, |
Lines 1664-1669
static void
Link Here
|
1664 |
vtscsi_init_ctrl_tmf_req(struct vtscsi_softc *sc, struct ccb_hdr *ccbh, |
1705 |
vtscsi_init_ctrl_tmf_req(struct vtscsi_softc *sc, struct ccb_hdr *ccbh, |
1665 |
uint32_t subtype, uintptr_t tag, struct virtio_scsi_ctrl_tmf_req *tmf_req) |
1706 |
uint32_t subtype, uintptr_t tag, struct virtio_scsi_ctrl_tmf_req *tmf_req) |
1666 |
{ |
1707 |
{ |
|
|
1708 |
// I don't know what if anything I'm breaking by silently replacing |
1709 |
// the tag value with a second atomic 32 bit counter. |
1710 |
// |
1711 |
// Silence compiler warnings about unused arguments. |
1712 |
(void)tag; |
1713 |
|
1714 |
do { |
1715 |
tag = atomic_fetchadd_32(&counter, 1); |
1716 |
} while ( __builtin_expect(tag == UINT32_MAX, false) ); |
1667 |
|
1717 |
|
1668 |
vtscsi_set_request_lun(ccbh, tmf_req->lun); |
1718 |
vtscsi_set_request_lun(ccbh, tmf_req->lun); |
1669 |
|
1719 |
|