spinlock_t jp_lock; /* protects jp_jobid */
char jp_jobid[LUSTRE_JOBID_SIZE];
unsigned int jp_joblen;
- atomic_t jp_refcount;
+ struct kref jp_refcount;
pid_t jp_pid;
};
rhashtable_walk_enter(&session_jobids, &iter);
rhashtable_walk_start(&iter);
while ((sj = rhashtable_walk_next(&iter)) != NULL) {
+ if (IS_ERR(sj)) {
+ if (PTR_ERR(sj) == -EAGAIN)
+ continue;
+ break;
+ }
if (!hlist_empty(&sj->sj_session->tasks[PIDTYPE_SID])) {
remaining++;
continue;
/* Just copied from kernel for the kernels which doesn't
* have access_process_vm() exported
*/
- struct vm_area_struct *vma;
+ struct vm_area_struct *vma = NULL;
struct page *page;
void *old_buf = buf;
int bytes, rc, offset;
void *maddr;
-#if defined(HAVE_GET_USER_PAGES_GUP_FLAGS)
+#if defined(HAVE_GET_USER_PAGES_WITHOUT_VMA)
+ rc = get_user_pages(addr, 1, write ? FOLL_WRITE : 0, &page);
+ if (rc > 0)
+ vma = vma_lookup(mm, addr);
+#elif defined(HAVE_GET_USER_PAGES_GUP_FLAGS)
rc = get_user_pages(addr, 1, write ? FOLL_WRITE : 0, &page,
&vma);
#elif defined(HAVE_GET_USER_PAGES_6ARG)
#else
rc = get_user_pages(tsk, mm, addr, 1, write, 1, &page, &vma);
#endif
- if (rc <= 0)
+ if (rc <= 0 || !vma)
break;
bytes = len;
* then an upcall could be issued here to get the jobid by utilizing
* the userspace tools/API. Then, the jobid must be cached.
*/
-int jobid_get_from_environ(char *jobid_var, char *jobid, int *jobid_len)
+static int jobid_get_from_environ(char *jobid_var, char *jobid, int *jobid_len)
{
int rc;
return 0;
if (jobid == NULL) {
- WARN_ON_ONCE(atomic_read(&pidmap->jp_refcount) != 1);
+ WARN_ON_ONCE(kref_read(&pidmap->jp_refcount) != 1);
return 1;
}
spin_lock(&pidmap->jp_lock);
/* prevent newly inserted items from deleting */
- if (jobid[0] == '\0' && atomic_read(&pidmap->jp_refcount) == 1)
+ if (jobid[0] == '\0' && kref_read(&pidmap->jp_refcount) == 1)
rc = 1;
else if (ktime_get_real_seconds() - pidmap->jp_time > DELETE_INTERVAL)
rc = 1;
static bool jobid_name_is_valid(char *jobid)
{
const char *const lustre_reserved[] = { "ll_ping", "ptlrpc",
- "ldlm", "ll_sa", NULL };
+ "ldlm", "ll_sa", "kworker",
+ "kswapd", "writeback", "irq",
+ "ksoftirq", NULL };
int i;
if (jobid[0] == '\0')
rcu_read_lock();
jid = jobid_current();
if (jid) {
- strlcpy(jobid, jid, joblen);
+ strscpy(jobid, jid, joblen);
joblen = strlen(jobid);
} else {
rc = -ENOENT;
* hash list, init @jp_refcount as 1 to make sure memory
* could be not freed during access.
*/
- atomic_set(&pidmap->jp_refcount, 1);
+ kref_init(&pidmap->jp_refcount);
/*
* Add the newly created map to the hash, on key collision we
spin_lock(&pidmap->jp_lock);
if (!rc) {
pidmap->jp_joblen = env_len;
- strlcpy(pidmap->jp_jobid, env_jobid,
+ strscpy(pidmap->jp_jobid, env_jobid,
sizeof(pidmap->jp_jobid));
rc = 0;
} else if (rc == -ENOENT) {
* If a cached missing entry was found, return -ENOENT.
*/
if (pidmap->jp_joblen) {
- strlcpy(jobid, pidmap->jp_jobid, joblen);
+ strscpy(jobid, pidmap->jp_jobid, joblen);
joblen = pidmap->jp_joblen;
rc = 0;
} else if (!rc) {
}
/*
+ * jobid_print_current_comm()
+ *
+ * Print current comm name into the provided jobid buffer, and trim names of
+ * kernel threads like "kworker/0:0" to "kworker" or "ll_sa_12345" to "ll_sa"
+ *
+ * Return: number of chars printed to jobid
+ */
+static int jobid_print_current_comm(char *jobid, ssize_t joblen)
+{
+ const char *const names[] = {"kworker", "kswapd", "ll_sa", "ll_agl",
+ "ldlm_bl", NULL};
+ int i;
+
+ if (current->flags & PF_KTHREAD) {
+ for (i = 0; names[i] != NULL; i++) {
+ if (strncmp(current->comm, names[i],
+ strlen(names[i])) == 0)
+ return snprintf(jobid, joblen, "%s", names[i]);
+ }
+ }
+
+ return snprintf(jobid, joblen, "%s", current->comm);
+}
+
+/*
* jobid_interpret_string()
*
* Interpret the jobfmt string to expand specified fields, like coredumps do:
switch ((f = *jobfmt++)) {
case 'e': /* executable name */
- l = snprintf(jobid, joblen, "%s", current->comm);
+ l = jobid_print_current_comm(jobid, joblen);
break;
case 'g': /* group ID */
l = snprintf(jobid, joblen, "%u",
/*
* Hash operations for pid<->jobid
*/
-static unsigned jobid_hashfn(struct cfs_hash *hs, const void *key,
- unsigned mask)
+static unsigned int
+jobid_hashfn(struct cfs_hash *hs, const void *key, const unsigned int bits)
{
- return cfs_hash_djb2_hash(key, sizeof(pid_t), mask);
+ return cfs_hash_djb2_hash(key, sizeof(pid_t), bits);
}
static void *jobid_key(struct hlist_node *hnode)
pidmap = hlist_entry(hnode, struct jobid_pid_map, jp_hash);
- atomic_inc(&pidmap->jp_refcount);
+ kref_get(&pidmap->jp_refcount);
+}
+
+static void jobid_put_locked_free(struct kref *kref)
+{
+ struct jobid_pid_map *pidmap = container_of(kref, struct jobid_pid_map,
+ jp_refcount);
+
+ CDEBUG(D_INFO, "Freeing: %d->%s\n", pidmap->jp_pid, pidmap->jp_jobid);
+ OBD_FREE_PTR(pidmap);
}
static void jobid_put_locked(struct cfs_hash *hs, struct hlist_node *hnode)
return;
pidmap = hlist_entry(hnode, struct jobid_pid_map, jp_hash);
- LASSERT(atomic_read(&pidmap->jp_refcount) > 0);
- if (atomic_dec_and_test(&pidmap->jp_refcount)) {
- CDEBUG(D_INFO, "Freeing: %d->%s\n",
- pidmap->jp_pid, pidmap->jp_jobid);
-
- OBD_FREE_PTR(pidmap);
- }
+ LASSERT(kref_read(&pidmap->jp_refcount) > 0);
+ kref_put(&pidmap->jp_refcount, jobid_put_locked_free);
}
static struct cfs_hash_ops jobid_hash_ops = {
*/
int lustre_get_jobid(char *jobid, size_t joblen)
{
+ char id[LUSTRE_JOBID_SIZE] = "";
+ int len = min_t(int, joblen, LUSTRE_JOBID_SIZE);
int rc = 0;
ENTRY;
if (strcmp(obd_jobid_var, JOBSTATS_DISABLE) == 0) {
/* Jobstats isn't enabled */
memset(jobid, 0, joblen);
- } else if (strcmp(obd_jobid_var, JOBSTATS_NODELOCAL) == 0) {
+ RETURN(0);
+ }
+
+ if (strcmp(obd_jobid_var, JOBSTATS_NODELOCAL) == 0) {
/* Whole node dedicated to single job */
- rc = jobid_interpret_string(obd_jobid_name, jobid, joblen);
+ rc = jobid_interpret_string(obd_jobid_name, id, len);
} else if (strcmp(obd_jobid_var, JOBSTATS_PROCNAME_UID) == 0) {
- rc = jobid_interpret_string("%e.%u", jobid, joblen);
+ rc = jobid_interpret_string("%e.%u", id, len);
} else if (strcmp(obd_jobid_var, JOBSTATS_SESSION) == 0 ||
jobid_name_is_valid(current->comm)) {
/*
*/
rc = -EAGAIN;
if (!strnstr(obd_jobid_name, "%j", joblen))
- rc = jobid_get_from_cache(jobid, joblen);
+ rc = jobid_get_from_cache(id, len);
/* fall back to jobid_name if jobid_var not available */
if (rc < 0) {
int rc2 = jobid_interpret_string(obd_jobid_name,
- jobid, joblen);
+ id, len);
if (!rc2)
rc = 0;
}
}
+ memcpy(jobid, id, len);
RETURN(rc);
}
EXPORT_SYMBOL(lustre_get_jobid);
if (jobid_hash == NULL)
return;
- strlcpy(jobid, find_jobid, sizeof(jobid));
+ strscpy(jobid, find_jobid, sizeof(jobid));
/* trim \n off the end of the incoming jobid */
end = strchr(jobid, '\n');
if (end && *end == '\n')