/* * Start a context * Code here similar to afu_ioctl_start_work(). */ int cxl_start_context(struct cxl_context *ctx, u64 wed, struct task_struct *task) { int rc = 0; bool kernel = true; pr_devel("%s: pe: %i\n", __func__, ctx->pe); mutex_lock(&ctx->status_mutex); if (ctx->status == STARTED) goto out; /* already started */ if (task) { ctx->pid = get_task_pid(task, PIDTYPE_PID); get_pid(ctx->pid); kernel = false; } cxl_ctx_get(); if ((rc = cxl_attach_process(ctx, kernel, wed , 0))) { put_pid(ctx->pid); cxl_ctx_put(); goto out; } ctx->status = STARTED; out: mutex_unlock(&ctx->status_mutex); return rc; }
static int afu_release(struct inode *inode, struct file *file) { struct cxl_context *ctx = file->private_data; pr_devel("%s: closing cxl file descriptor. pe: %i\n", __func__, ctx->pe); cxl_context_detach(ctx); mutex_lock(&ctx->mapping_lock); ctx->mapping = NULL; mutex_unlock(&ctx->mapping_lock); put_device(&ctx->afu->dev); /* * At this this point all bottom halfs have finished and we should be * getting no more IRQs from the hardware for this context. Once it's * removed from the IDR (and RCU synchronised) it's safe to free the * sstp and context. */ cxl_context_free(ctx); cxl_ctx_put(); return 0; }
/* * Start a context * Code here similar to afu_ioctl_start_work(). */ int cxl_start_context(struct cxl_context *ctx, u64 wed, struct task_struct *task) { int rc = 0; bool kernel = true; pr_devel("%s: pe: %i\n", __func__, ctx->pe); mutex_lock(&ctx->status_mutex); if (ctx->status == STARTED) goto out; /* already started */ /* * Increment the mapped context count for adapter. This also checks * if adapter_context_lock is taken. */ rc = cxl_adapter_context_get(ctx->afu->adapter); if (rc) goto out; if (task) { ctx->pid = get_task_pid(task, PIDTYPE_PID); kernel = false; /* acquire a reference to the task's mm */ ctx->mm = get_task_mm(current); /* ensure this mm_struct can't be freed */ cxl_context_mm_count_get(ctx); if (ctx->mm) { /* decrement the use count from above */ mmput(ctx->mm); /* make TLBIs for this context global */ mm_context_add_copro(ctx->mm); } } /* * Increment driver use count. Enables global TLBIs for hash * and callbacks to handle the segment table */ cxl_ctx_get(); /* See the comment in afu_ioctl_start_work() */ smp_mb(); if ((rc = cxl_ops->attach_process(ctx, kernel, wed, 0))) { put_pid(ctx->pid); ctx->pid = NULL; cxl_adapter_context_put(ctx->afu->adapter); cxl_ctx_put(); if (task) { cxl_context_mm_count_put(ctx); if (ctx->mm) mm_context_remove_copro(ctx->mm); } goto out; } ctx->status = STARTED; out: mutex_unlock(&ctx->status_mutex); return rc; }