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

Commit 295ab1b5 authored by Karen Xie's avatar Karen Xie Committed by James Bottomley
Browse files

cxgb3i: use kref to track ddp usage



The iscsi ddp functionality could be used by multiple iscsi entities,
add a refcnt to keep track of it, so we would not release it pre-maturely.

Signed-off-by: default avatarKaren Xie <kxie@chelsio.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent d11b6916
Loading
Loading
Loading
Loading
+33 −21
Original line number Diff line number Diff line
@@ -598,22 +598,24 @@ int cxgb3i_adapter_ddp_info(struct t3cdev *tdev,
 * release all the resource held by the ddp pagepod manager for a given
 * adapter if needed
 */
void cxgb3i_ddp_cleanup(struct t3cdev *tdev)

static void ddp_cleanup(struct kref *kref)
{
	struct cxgb3i_ddp_info *ddp = container_of(kref,
						struct cxgb3i_ddp_info,
						refcnt);
	int i = 0;
	struct cxgb3i_ddp_info *ddp = (struct cxgb3i_ddp_info *)tdev->ulp_iscsi;

	ddp_log_info("t3dev 0x%p, release ddp 0x%p.\n", tdev, ddp);
	ddp_log_info("kref release ddp 0x%p, t3dev 0x%p.\n", ddp, ddp->tdev);

	if (ddp) {
		tdev->ulp_iscsi = NULL;
	ddp->tdev->ulp_iscsi = NULL;
	while (i < ddp->nppods) {
		struct cxgb3i_gather_list *gl = ddp->gl_map[i];
		if (gl) {
			int npods = (gl->nelem + PPOD_PAGES_MAX - 1)
					>> PPOD_PAGES_SHIFT;
			ddp_log_info("t3dev 0x%p, ddp %d + %d.\n",
						tdev, i, npods);
					ddp->tdev, i, npods);
			kfree(gl);
			ddp_free_gl_skb(ddp, i, npods);
			i += npods;
@@ -622,6 +624,14 @@ void cxgb3i_ddp_cleanup(struct t3cdev *tdev)
	}
	cxgb3i_free_big_mem(ddp);
}

void cxgb3i_ddp_cleanup(struct t3cdev *tdev)
{
	struct cxgb3i_ddp_info *ddp = (struct cxgb3i_ddp_info *)tdev->ulp_iscsi;

	ddp_log_info("t3dev 0x%p, release ddp 0x%p.\n", tdev, ddp);
	if (ddp)
		kref_put(&ddp->refcnt, ddp_cleanup);
}

/**
@@ -631,12 +641,13 @@ void cxgb3i_ddp_cleanup(struct t3cdev *tdev)
 */
static void ddp_init(struct t3cdev *tdev)
{
	struct cxgb3i_ddp_info *ddp;
	struct cxgb3i_ddp_info *ddp = tdev->ulp_iscsi;
	struct ulp_iscsi_info uinfo;
	unsigned int ppmax, bits;
	int i, err;

	if (tdev->ulp_iscsi) {
	if (ddp) {
		kref_get(&ddp->refcnt);
		ddp_log_warn("t3dev 0x%p, ddp 0x%p already set up.\n",
				tdev, tdev->ulp_iscsi);
		return;
@@ -670,6 +681,7 @@ static void ddp_init(struct t3cdev *tdev)
					  ppmax *
					  sizeof(struct cxgb3i_gather_list *));
	spin_lock_init(&ddp->map_lock);
	kref_init(&ddp->refcnt);

	ddp->tdev = tdev;
	ddp->pdev = uinfo.pdev;
+2 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ struct cxgb3i_gather_list {
 * struct cxgb3i_ddp_info - cxgb3i direct data placement for pdu payload
 *
 * @list:	list head to link elements
 * @refcnt:	ref. count
 * @tdev:	pointer to t3cdev used by cxgb3 driver
 * @max_txsz:	max tx packet size for ddp
 * @max_rxsz:	max rx packet size for ddp
@@ -70,6 +71,7 @@ struct cxgb3i_gather_list {
 */
struct cxgb3i_ddp_info {
	struct list_head list;
	struct kref refcnt;
	struct t3cdev *tdev;
	struct pci_dev *pdev;
	unsigned int max_txsz;