Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d1824329 authored by Sudeep Dutt's avatar Sudeep Dutt Committed by Greg Kroah-Hartman
Browse files

misc: mic: SCIF RMA nodeqp and minor miscellaneous changes



This patch adds the SCIF kernel node QP control messages required to
enable SCIF RMAs. Examples of such node QP control messages include
registration, unregistration, remote memory allocation requests,
remote memory unmap and SCIF remote fence requests.

The patch also updates the SCIF driver with minor changes required to
enable SCIF RMAs by adding the new files to the build, initializing
RMA specific information during SCIF endpoint creation, reserving SCIF
DMA channels, initializing SCIF RMA specific global data structures,
adding the IOCTL hooks required for SCIF RMAs and updating RMA
specific debugfs hooks.

Reviewed-by: default avatarAshutosh Dixit <ashutosh.dixit@intel.com>
Reviewed-by: default avatarNikhil Rao <nikhil.rao@intel.com>
Signed-off-by: default avatarSudeep Dutt <sudeep.dutt@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 564c8d8d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ comment "SCIF Driver"
config SCIF
	tristate "SCIF Driver"
	depends on 64BIT && PCI && X86 && SCIF_BUS
	select IOMMU_IOVA
	help
	  This enables SCIF Driver support for the Intel Many Integrated
	  Core (MIC) family of PCIe form factor coprocessor devices that
+5 −0
Original line number Diff line number Diff line
@@ -13,3 +13,8 @@ scif-objs += scif_epd.o
scif-objs += scif_rb.o
scif-objs += scif_nodeqp.o
scif-objs += scif_nm.o
scif-objs += scif_dma.o
scif-objs += scif_fence.o
scif-objs += scif_mmap.o
scif-objs += scif_rma.o
scif-objs += scif_rma_list.o
+27 −6
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ scif_epd_t scif_open(void)
	mutex_init(&ep->sendlock);
	mutex_init(&ep->recvlock);

	scif_rma_ep_init(ep);
	ep->state = SCIFEP_UNBOUND;
	dev_dbg(scif_info.mdev.this_device,
		"SCIFAPI open: ep %p success\n", ep);
@@ -184,8 +185,11 @@ int scif_close(scif_epd_t epd)

	switch (oldstate) {
	case SCIFEP_ZOMBIE:
		dev_err(scif_info.mdev.this_device,
			"SCIFAPI close: zombie state unexpected\n");
	case SCIFEP_DISCONNECTED:
		spin_unlock(&ep->lock);
		scif_unregister_all_windows(epd);
		/* Remove from the disconnected list */
		mutex_lock(&scif_info.connlock);
		list_for_each_safe(pos, tmpq, &scif_info.disconnected) {
@@ -207,6 +211,7 @@ int scif_close(scif_epd_t epd)
	case SCIFEP_CLOSING:
	{
		spin_unlock(&ep->lock);
		scif_unregister_all_windows(epd);
		scif_disconnect_ep(ep);
		break;
	}
@@ -218,7 +223,7 @@ int scif_close(scif_epd_t epd)
		struct scif_endpt *aep;

		spin_unlock(&ep->lock);
		spin_lock(&scif_info.eplock);
		mutex_lock(&scif_info.eplock);

		/* remove from listen list */
		list_for_each_safe(pos, tmpq, &scif_info.listen) {
@@ -240,7 +245,7 @@ int scif_close(scif_epd_t epd)
					break;
				}
			}
			spin_unlock(&scif_info.eplock);
			mutex_unlock(&scif_info.eplock);
			mutex_lock(&scif_info.connlock);
			list_for_each_safe(pos, tmpq, &scif_info.connected) {
				tmpep = list_entry(pos,
@@ -260,13 +265,13 @@ int scif_close(scif_epd_t epd)
			}
			mutex_unlock(&scif_info.connlock);
			scif_teardown_ep(aep);
			spin_lock(&scif_info.eplock);
			mutex_lock(&scif_info.eplock);
			scif_add_epd_to_zombie_list(aep, SCIF_EPLOCK_HELD);
			ep->acceptcnt--;
		}

		spin_lock(&ep->lock);
		spin_unlock(&scif_info.eplock);
		mutex_unlock(&scif_info.eplock);

		/* Remove and reject any pending connection requests. */
		while (ep->conreqcnt) {
@@ -428,9 +433,9 @@ int scif_listen(scif_epd_t epd, int backlog)
	scif_teardown_ep(ep);
	ep->qp_info.qp = NULL;

	spin_lock(&scif_info.eplock);
	mutex_lock(&scif_info.eplock);
	list_add_tail(&ep->list, &scif_info.listen);
	spin_unlock(&scif_info.eplock);
	mutex_unlock(&scif_info.eplock);
	return 0;
}
EXPORT_SYMBOL_GPL(scif_listen);
@@ -469,6 +474,13 @@ static int scif_conn_func(struct scif_endpt *ep)
	struct scifmsg msg;
	struct device *spdev;

	err = scif_reserve_dma_chan(ep);
	if (err) {
		dev_err(&ep->remote_dev->sdev->dev,
			"%s %d err %d\n", __func__, __LINE__, err);
		ep->state = SCIFEP_BOUND;
		goto connect_error_simple;
	}
	/* Initiate the first part of the endpoint QP setup */
	err = scif_setup_qp_connect(ep->qp_info.qp, &ep->qp_info.qp_offset,
				    SCIF_ENDPT_QP_SIZE, ep->remote_dev);
@@ -804,6 +816,15 @@ int scif_accept(scif_epd_t epd, struct scif_port_id *peer,
	cep->remote_dev = &scif_dev[peer->node];
	cep->remote_ep = conreq->msg.payload[0];

	scif_rma_ep_init(cep);

	err = scif_reserve_dma_chan(cep);
	if (err) {
		dev_err(scif_info.mdev.this_device,
			"%s %d err %d\n", __func__, __LINE__, err);
		goto scif_accept_error_qpalloc;
	}

	cep->qp_info.qp = kzalloc(sizeof(*cep->qp_info.qp), GFP_KERNEL);
	if (!cep->qp_info.qp) {
		err = -ENOMEM;
+81 −4
Original line number Diff line number Diff line
@@ -62,10 +62,87 @@ static const struct file_operations scif_dev_ops = {
	.release = scif_dev_test_release
};

void __init scif_init_debugfs(void)
static void scif_display_window(struct scif_window *window, struct seq_file *s)
{
	int j;
	struct scatterlist *sg;
	scif_pinned_pages_t pin = window->pinned_pages;

	seq_printf(s, "window %p type %d temp %d offset 0x%llx ",
		   window, window->type, window->temp, window->offset);
	seq_printf(s, "nr_pages 0x%llx nr_contig_chunks 0x%x prot %d ",
		   window->nr_pages, window->nr_contig_chunks, window->prot);
	seq_printf(s, "ref_count %d magic 0x%llx peer_window 0x%llx ",
		   window->ref_count, window->magic, window->peer_window);
	seq_printf(s, "unreg_state 0x%x va_for_temp 0x%lx\n",
		   window->unreg_state, window->va_for_temp);

	for (j = 0; j < window->nr_contig_chunks; j++)
		seq_printf(s, "page[%d] dma_addr 0x%llx num_pages 0x%llx\n", j,
			   window->dma_addr[j], window->num_pages[j]);

	if (window->type == SCIF_WINDOW_SELF && pin)
		for (j = 0; j < window->nr_pages; j++)
			seq_printf(s, "page[%d] = pinned_pages %p address %p\n",
				   j, pin->pages[j],
				   page_address(pin->pages[j]));

	if (window->st)
		for_each_sg(window->st->sgl, sg, window->st->nents, j)
			seq_printf(s, "sg[%d] dma addr 0x%llx length 0x%x\n",
				   j, sg_dma_address(sg), sg_dma_len(sg));
}

static void scif_display_all_windows(struct list_head *head, struct seq_file *s)
{
	struct dentry *d;
	struct list_head *item;
	struct scif_window *window;

	list_for_each(item, head) {
		window = list_entry(item, struct scif_window, list);
		scif_display_window(window, s);
	}
}

static int scif_rma_test(struct seq_file *s, void *unused)
{
	struct scif_endpt *ep;
	struct list_head *pos;

	mutex_lock(&scif_info.connlock);
	list_for_each(pos, &scif_info.connected) {
		ep = list_entry(pos, struct scif_endpt, list);
		seq_printf(s, "ep %p self windows\n", ep);
		mutex_lock(&ep->rma_info.rma_lock);
		scif_display_all_windows(&ep->rma_info.reg_list, s);
		seq_printf(s, "ep %p remote windows\n", ep);
		scif_display_all_windows(&ep->rma_info.remote_reg_list, s);
		mutex_unlock(&ep->rma_info.rma_lock);
	}
	mutex_unlock(&scif_info.connlock);
	return 0;
}

static int scif_rma_test_open(struct inode *inode, struct file *file)
{
	return single_open(file, scif_rma_test, inode->i_private);
}

static int scif_rma_test_release(struct inode *inode, struct file *file)
{
	return single_release(inode, file);
}

static const struct file_operations scif_rma_ops = {
	.owner   = THIS_MODULE,
	.open    = scif_rma_test_open,
	.read    = seq_read,
	.llseek  = seq_lseek,
	.release = scif_rma_test_release
};

void __init scif_init_debugfs(void)
{
	scif_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL);
	if (!scif_dbg) {
		dev_err(scif_info.mdev.this_device,
@@ -73,8 +150,8 @@ void __init scif_init_debugfs(void)
		return;
	}

	d = debugfs_create_file("scif_dev", 0444, scif_dbg,
				NULL, &scif_dev_ops);
	debugfs_create_file("scif_dev", 0444, scif_dbg, NULL, &scif_dev_ops);
	debugfs_create_file("scif_rma", 0444, scif_dbg, NULL, &scif_rma_ops);
	debugfs_create_u8("en_msg_log", 0666, scif_dbg, &scif_info.en_msg_log);
	debugfs_create_u8("p2p_enable", 0666, scif_dbg, &scif_info.p2p_enable);
}
+15 −11
Original line number Diff line number Diff line
@@ -65,14 +65,14 @@ void scif_teardown_ep(void *endpt)
void scif_add_epd_to_zombie_list(struct scif_endpt *ep, bool eplock_held)
{
	if (!eplock_held)
		spin_lock(&scif_info.eplock);
		mutex_lock(&scif_info.eplock);
	spin_lock(&ep->lock);
	ep->state = SCIFEP_ZOMBIE;
	spin_unlock(&ep->lock);
	list_add_tail(&ep->list, &scif_info.zombie);
	scif_info.nr_zombies++;
	if (!eplock_held)
		spin_unlock(&scif_info.eplock);
		mutex_unlock(&scif_info.eplock);
	schedule_work(&scif_info.misc_work);
}

@@ -81,16 +81,15 @@ static struct scif_endpt *scif_find_listen_ep(u16 port)
	struct scif_endpt *ep = NULL;
	struct list_head *pos, *tmpq;

	spin_lock(&scif_info.eplock);
	mutex_lock(&scif_info.eplock);
	list_for_each_safe(pos, tmpq, &scif_info.listen) {
		ep = list_entry(pos, struct scif_endpt, list);
		if (ep->port.port == port) {
			spin_lock(&ep->lock);
			spin_unlock(&scif_info.eplock);
			mutex_unlock(&scif_info.eplock);
			return ep;
		}
	}
	spin_unlock(&scif_info.eplock);
	mutex_unlock(&scif_info.eplock);
	return NULL;
}

@@ -99,14 +98,17 @@ void scif_cleanup_zombie_epd(void)
	struct list_head *pos, *tmpq;
	struct scif_endpt *ep;

	spin_lock(&scif_info.eplock);
	mutex_lock(&scif_info.eplock);
	list_for_each_safe(pos, tmpq, &scif_info.zombie) {
		ep = list_entry(pos, struct scif_endpt, list);
		if (scif_rma_ep_can_uninit(ep)) {
			list_del(pos);
			scif_info.nr_zombies--;
			put_iova_domain(&ep->rma_info.iovad);
			kfree(ep);
		}
	spin_unlock(&scif_info.eplock);
	}
	mutex_unlock(&scif_info.eplock);
}

/**
@@ -137,6 +139,8 @@ void scif_cnctreq(struct scif_dev *scifdev, struct scifmsg *msg)
	if (!ep)
		/*  Send reject due to no listening ports */
		goto conreq_sendrej_free;
	else
		spin_lock(&ep->lock);

	if (ep->backlog <= ep->conreqcnt) {
		/*  Send reject due to too many pending requests */
Loading