All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Vetter <daniel@ffwll.ch>
To: Marius Vlad <marius.c.vlad@intel.com>
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH i-g-t 1/3] lib/{igt_sysfs, igt_aux}: Make available to other users kick_fbcon() (unbind_fbcon()), and added helpers to igt_aux.
Date: Mon, 24 Oct 2016 10:40:37 +0200	[thread overview]
Message-ID: <20161024084037.GG20761@phenom.ffwll.local> (raw)
In-Reply-To: <20161020193649.11701-2-marius.c.vlad@intel.com>

On Thu, Oct 20, 2016 at 10:36:47PM +0300, Marius Vlad wrote:
> Previously under unbind_fbcon(), disable/enable framebuffer console.
> 
> lib/igt_aux: Added helpers to help convert sh scripts to C version. libkmod and
> procps interface.
> 
> Signed-off-by: Marius Vlad <marius.c.vlad@intel.com>
> ---
>  configure.ac    |   2 +
>  lib/Makefile.am |   2 +
>  lib/igt_aux.c   | 278 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  lib/igt_aux.h   |   7 ++
>  lib/igt_gvt.c   |  43 +--------
>  lib/igt_sysfs.c |  54 +++++++++++
>  lib/igt_sysfs.h |   2 +
>  7 files changed, 347 insertions(+), 41 deletions(-)

If you go with extracting stuff into helpers I'd go with a new helper
library like igt_kmod.c. Or just keep it in-line with tests, extracting
code is imo overrated ;-)

Also pls make sure the docs are correct and look good, there's a bunch of
issues with them (like non-matching function names between comment and
actual code).
-Daniel

> 
> diff --git a/configure.ac b/configure.ac
> index 735cfd5..2c6e49d 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -121,6 +121,8 @@ AC_SUBST(ASSEMBLER_WARN_CFLAGS)
>  
>  PKG_CHECK_MODULES(DRM, [libdrm])
>  PKG_CHECK_MODULES(PCIACCESS, [pciaccess >= 0.10])
> +PKG_CHECK_MODULES(KMOD, [libkmod])
> +PKG_CHECK_MODULES(PROCPS, [libprocps])
>  
>  case "$target_cpu" in
>  	x86*|i?86)
> diff --git a/lib/Makefile.am b/lib/Makefile.am
> index 4c0893d..e1737bd 100644
> --- a/lib/Makefile.am
> +++ b/lib/Makefile.am
> @@ -34,6 +34,8 @@ AM_CFLAGS += $(CAIRO_CFLAGS)
>  libintel_tools_la_LIBADD = \
>  	$(DRM_LIBS) \
>  	$(PCIACCESS_LIBS) \
> +	$(PROCPS_LIBS) \
> +	$(KMOD_LIBS) \
>  	$(CAIRO_LIBS) \
>  	$(LIBUDEV_LIBS) \
>  	$(LIBUNWIND_LIBS) \
> diff --git a/lib/igt_aux.c b/lib/igt_aux.c
> index 421f6d4..d150818 100644
> --- a/lib/igt_aux.c
> +++ b/lib/igt_aux.c
> @@ -51,6 +51,9 @@
>  #include <termios.h>
>  #include <assert.h>
>  
> +#include <proc/readproc.h>
> +#include <libkmod.h>
> +
>  #include "drmtest.h"
>  #include "i915_drm.h"
>  #include "intel_chipset.h"
> @@ -1193,6 +1196,281 @@ void igt_set_module_param_int(const char *name, int val)
>  	igt_set_module_param(name, str);
>  }
>  
> +/**
> + * igt_pkill:
> + * @sig: Signal to send
> + * @name: Name of process in the form found in /proc/pid/comm (limited to 15
> + * chars)
> + * @returns: 0 in case the process is not found running or the signal has been
> + * sent successfully or -1 otherwise.
> + *
> + * This function sends the signal @sig for a process found in process table
> + * with name @comm.
> + */
> +int
> +igt_pkill(int sig, const char *comm)
> +{
> +	int err = 0, try = 5;
> +	PROCTAB *proc;
> +	proc_t *proc_info;
> +
> +	proc = openproc(PROC_FILLCOM | PROC_FILLSTAT | PROC_FILLARG);
> +	igt_assert(proc != NULL);
> +
> +	while ((proc_info = readproc(proc, NULL))) {
> +		if (proc_info &&
> +		    !strncasecmp(proc_info->cmd, comm, sizeof(proc_info->cmd))) {
> +			switch (sig) {
> +			case SIGTERM:
> +			case SIGKILL:
> +				do {
> +					kill(proc_info->tid, sig);
> +				} while (kill(proc_info->tid, 0) < 0 && try--);
> +
> +				if (kill(proc_info->tid, 0) < 0)
> +					err = -1;
> +				break;
> +			default:
> +				if (kill(proc_info->tid, sig) < 0)
> +					err = -1;
> +				break;
> +			}
> +
> +			freeproc(proc_info);
> +			break;
> +		}
> +		freeproc(proc_info);
> +	}
> +
> +	closeproc(proc);
> +	return err;
> +}
> +
> +/**
> + * igt_kill:
> + * @sig: Signal to send.
> + * @pid: Process pid to send.
> + * @returns: 0 in case of success or -1 otherwise.
> + *
> + * This function is identical to igt_pkill() only that it searches the process
> + * table using @pid instead of comm name.
> + *
> + */
> +int
> +igt_kill(int sig, pid_t pid)
> +{
> +	int err = 0, try = 5;
> +	PROCTAB *proc;
> +	proc_t *proc_info;
> +
> +	proc = openproc(PROC_PID | PROC_FILLSTAT | PROC_FILLARG);
> +	igt_assert(proc != NULL);
> +
> +	while ((proc_info = readproc(proc, NULL))) {
> +		if (proc_info && proc_info->tid == pid) {
> +			switch (sig) {
> +			case SIGTERM:
> +			case SIGKILL:
> +				do {
> +					kill(proc_info->tid, sig);
> +				} while (kill(proc_info->tid, 0) < 0 && try--);
> +
> +				if (kill(proc_info->tid, 0) < 0)
> +					err = -1;
> +				break;
> +			default:
> +				if (kill(proc_info->tid, sig) < 0)
> +					err = -1;
> +				break;
> +			}
> +			freeproc(proc_info);
> +			break;
> +		}
> +		freeproc(proc_info);
> +	}
> +
> +	closeproc(proc);
> +	return err;
> +}
> +
> +static bool
> +igt_module_in_use(struct kmod_module *kmod)
> +{
> +	int err;
> +
> +	err = kmod_module_get_initstate(kmod);
> +
> +	/* if compiled builtin or does not exist */
> +	if (err == KMOD_MODULE_BUILTIN || err < 0)
> +		return false;
> +
> +	if (kmod_module_get_refcnt(kmod) != 0 ||
> +	    kmod_module_get_holders(kmod) != NULL)
> +		return true;
> +
> +
> +	return false;
> +}
> +
> +/**
> + * igt_lsmod:
> + * @mod_name: The name of the module.
> + * @returns: True in case the module has been found or false otherwise.
> + *
> + *
> + * Function to check the existance of module @mod_name in list of loaded kernel
> + * modules.
> + *
> + */
> +bool
> +igt_lsmod_has_module(const char *mod_name)
> +{
> +	struct kmod_list *mod, *list;
> +	struct kmod_ctx *ctx;
> +	bool ret = false;
> +
> +	ctx = kmod_new(NULL, NULL);
> +	igt_assert(ctx != NULL);
> +
> +	if (kmod_module_new_from_loaded(ctx, &list) < 0) {
> +		kmod_unref(ctx);
> +		return ret;
> +	}
> +
> +	kmod_list_foreach(mod, list) {
> +		struct kmod_module *kmod = kmod_module_get_module(mod);
> +		const char *kmod_name = kmod_module_get_name(kmod);
> +
> +		if (!strncasecmp(kmod_name, mod_name, strlen(kmod_name))) {
> +			kmod_module_unref(kmod);
> +			ret = true;
> +			break;
> +		}
> +		kmod_module_unref(kmod);
> +	}
> +
> +	kmod_module_unref_list(list);
> +	kmod_unref(ctx);
> +
> +	return ret;
> +}
> +
> +
> +/**
> + * igt_insmod:
> + * @mod_name: The name of the module
> + * @opts: Parameters for the module. NULL in case no parameters
> + * are to be passed, or a '\0' terminated string otherwise.
> + * @returns: 0 in case of success or -1 in case the module could not
> + * be loaded.
> + *
> + *
> + * This function loads a kernel module using the name specified in @mod_name.
> + *
> + * @Note: This functions doesn't automatically resolve other module
> + * dependencies so make make sure you load the dependencies module(s) before
> + * this one.
> + */
> +int
> +igt_insmod(const char *mod_name, const char *opts)
> +{
> +	struct kmod_ctx *ctx;
> +	struct kmod_module *kmod;
> +	int err = 0;
> +
> +	ctx = kmod_new(NULL, NULL);
> +	igt_assert(ctx != NULL);
> +
> +
> +	err = kmod_module_new_from_name(ctx, mod_name, &kmod);
> +	if (err < 0) {
> +		goto out;
> +	}
> +
> +	err = kmod_module_insert_module(kmod, 0, opts);
> +	if (err < 0) {
> +		switch (err) {
> +		case -EEXIST:
> +			igt_info("Module %s already inserted\n",
> +				 kmod_module_get_name(kmod));
> +			err = -1;
> +			break;
> +		case -ENOENT:
> +			igt_info("Unknown symbol in module %s or "
> +				 "unknown parameter\n",
> +				 kmod_module_get_name(kmod));
> +			err = -1;
> +			break;
> +		default:
> +			igt_info("Could not insert %s (%s)\n",
> +				 kmod_module_get_name(kmod), strerror(-err));
> +			err = -1;
> +			break;
> +		}
> +	}
> +out:
> +	kmod_module_unref(kmod);
> +	kmod_unref(ctx);
> +
> +	return err;
> +}
> +
> +
> +/**
> + * igt_rmmod:
> + * @mod_name: Module name.
> + * @force: A bool value to force removal. Note that his flag does not remove
> + * the module(s) that the module specified by @mod_name depends on. In other
> + * words you must igt_rmmod() the module(s) dependencies before calling it with
> + * @mod_name.
> + * @returns: 0 in case of success or -1 otherwise.
> + *
> + * Removes the module @mod_name.
> + *
> + */
> +int
> +igt_rmmod(const char *mod_name, bool force)
> +{
> +	struct kmod_ctx *ctx;
> +	struct kmod_module *kmod;
> +	int err, flags = 0;
> +
> +	ctx = kmod_new(NULL, NULL);
> +	igt_assert(ctx != NULL);
> +
> +	err = kmod_module_new_from_name(ctx, mod_name, &kmod);
> +	if (err < 0) {
> +		igt_info("Could not use module %s (%s)\n", mod_name,
> +				strerror(-err));
> +		err = -1;
> +		goto out;
> +	}
> +
> +	if (igt_module_in_use(kmod)) {
> +		igt_info("Module %s is in use\n", mod_name);
> +		err = -1;
> +		goto out;
> +	}
> +
> +	if (force) {
> +		flags |= KMOD_REMOVE_FORCE;
> +	}
> +
> +	err = kmod_module_remove_module(kmod, flags);
> +	if (err < 0) {
> +		igt_info("Could not remove module %s (%s)\n", mod_name,
> +				strerror(-err));
> +		err = -1;
> +	}
> +
> +out:
> +	kmod_module_unref(kmod);
> +	kmod_unref(ctx);
> +
> +	return err;
> +}
> +
> +
>  static struct igt_siglatency {
>  	timer_t timer;
>  	struct timespec target;
> diff --git a/lib/igt_aux.h b/lib/igt_aux.h
> index d30196b..7946923 100644
> --- a/lib/igt_aux.h
> +++ b/lib/igt_aux.h
> @@ -264,4 +264,11 @@ double igt_stop_siglatency(struct igt_mean *result);
>  void igt_set_module_param(const char *name, const char *val);
>  void igt_set_module_param_int(const char *name, int val);
>  
> +int igt_pkill(int sig, const char *comm);
> +int igt_kill(int sig, pid_t pid);
> +
> +bool igt_lsmod_has_module(const char *mod_name);
> +int igt_insmod(const char *mod_name, const char *opts);
> +int igt_rmmod(const char *mod_name, bool force);
> +
>  #endif /* IGT_AUX_H */
> diff --git a/lib/igt_gvt.c b/lib/igt_gvt.c
> index 0f332d1..8bbf9bd 100644
> --- a/lib/igt_gvt.c
> +++ b/lib/igt_gvt.c
> @@ -23,6 +23,7 @@
>  
>  #include "igt.h"
>  #include "igt_gvt.h"
> +#include "igt_sysfs.h"
>  
>  #include <dirent.h>
>  #include <unistd.h>
> @@ -46,49 +47,9 @@ static bool is_gvt_enabled(void)
>  	return enabled;
>  }
>  
> -static void unbind_fbcon(void)
> -{
> -	char buf[128];
> -	const char *path = "/sys/class/vtconsole";
> -	DIR *dir;
> -	struct dirent *vtcon;
> -
> -	dir = opendir(path);
> -	if (!dir)
> -		return;
> -
> -	while ((vtcon = readdir(dir))) {
> -		int fd, len;
> -
> -		if (strncmp(vtcon->d_name, "vtcon", 5))
> -			continue;
> -
> -		sprintf(buf, "%s/%s/name", path, vtcon->d_name);
> -		fd = open(buf, O_RDONLY);
> -		if (fd < 0)
> -			continue;
> -
> -		len = read(fd, buf, sizeof(buf) - 1);
> -		close(fd);
> -		if (len >= 0)
> -			buf[len] = '\0';
> -
> -		if (strstr(buf, "frame buffer device")) {
> -			sprintf(buf, "%s/%s/bind", path, vtcon->d_name);
> -			fd = open(buf, O_WRONLY);
> -			if (fd != -1) {
> -				igt_ignore_warn(write(fd, "1\n", 2));
> -				close(fd);
> -			}
> -			break;
> -		}
> -	}
> -	closedir(dir);
> -}
> -
>  static void unload_i915(void)
>  {
> -	unbind_fbcon();
> +	kick_fbcon(false);
>  	/* pkill alsact */
>  
>  	igt_ignore_warn(system("/sbin/modprobe -s -r i915"));
> diff --git a/lib/igt_sysfs.c b/lib/igt_sysfs.c
> index 612de75..0803659 100644
> --- a/lib/igt_sysfs.c
> +++ b/lib/igt_sysfs.c
> @@ -34,7 +34,11 @@
>  #include <fcntl.h>
>  #include <unistd.h>
>  #include <i915_drm.h>
> +#include <dirent.h>
> +#include <unistd.h>
> +#include <fcntl.h>
>  
> +#include "igt_core.h"
>  #include "igt_sysfs.h"
>  
>  /**
> @@ -391,3 +395,53 @@ bool igt_sysfs_set_boolean(int dir, const char *attr, bool value)
>  {
>  	return igt_sysfs_printf(dir, attr, "%d", value) == 1;
>  }
> +
> +/**
> + * kick_fbcon:
> + * @enable: boolean value
> + *
> + * This functions enables/disables the text console running on top of the
> + * framebuffer device.
> + */
> +void kick_fbcon(bool enable)
> +{
> +	char buf[128];
> +	const char *path = "/sys/class/vtconsole";
> +	DIR *dir;
> +	struct dirent *vtcon;
> +
> +	dir = opendir(path);
> +	if (!dir)
> +		return;
> +
> +	while ((vtcon = readdir(dir))) {
> +		int fd, len;
> +
> +		if (strncmp(vtcon->d_name, "vtcon", 5))
> +			continue;
> +
> +		sprintf(buf, "%s/%s/name", path, vtcon->d_name);
> +		fd = open(buf, O_RDONLY);
> +		if (fd < 0)
> +			continue;
> +
> +		len = read(fd, buf, sizeof(buf) - 1);
> +		close(fd);
> +		if (len >= 0)
> +			buf[len] = '\0';
> +
> +		if (strstr(buf, "frame buffer device")) {
> +			sprintf(buf, "%s/%s/bind", path, vtcon->d_name);
> +			fd = open(buf, O_WRONLY);
> +			if (fd != -1) {
> +				if (enable)
> +					igt_ignore_warn(write(fd, "1\n", 2));
> +				else
> +					igt_ignore_warn(write(fd, "0\n", 2));
> +				close(fd);
> +			}
> +			break;
> +		}
> +	}
> +	closedir(dir);
> +}
> diff --git a/lib/igt_sysfs.h b/lib/igt_sysfs.h
> index 4820066..a141894 100644
> --- a/lib/igt_sysfs.h
> +++ b/lib/igt_sysfs.h
> @@ -43,4 +43,6 @@ bool igt_sysfs_set_u32(int dir, const char *attr, uint32_t value);
>  bool igt_sysfs_get_boolean(int dir, const char *attr);
>  bool igt_sysfs_set_boolean(int dir, const char *attr, bool value);
>  
> +void kick_fbcon(bool enable);
> +
>  #endif /* __IGT_SYSFS_H__ */
> -- 
> 2.7.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  parent reply	other threads:[~2016-10-24  8:40 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-10-20 19:36 [PATCH i-g-t 0/3] Convert sh scripts to C variants Marius Vlad
2016-10-20 19:36 ` [PATCH i-g-t 1/3] lib/{igt_sysfs, igt_aux}: Make available to other users kick_fbcon() (unbind_fbcon()), and added helpers to igt_aux Marius Vlad
2016-10-20 20:09   ` Chris Wilson
2016-10-24 18:08     ` Marius Vlad
2016-10-24  8:40   ` Daniel Vetter [this message]
2016-10-26 21:02     ` Marius Vlad
2016-10-27  6:40       ` Daniel Vetter
2016-10-20 19:36 ` [PATCH i-g-t 2/3] tests/drv_module_reload_basic: Convert sh script to C version Marius Vlad
2016-10-20 19:52   ` Chris Wilson
2016-10-24 18:05     ` Marius Vlad
2016-10-24 20:34       ` Chris Wilson
2016-10-21  9:39   ` Petri Latvala
2016-10-24 18:06     ` Marius Vlad
2016-10-20 19:36 ` [PATCH i-g-t 3/3] tests/kms_sysfs_edid_timing: " Marius Vlad
2016-10-20 19:58   ` Chris Wilson
2016-10-20 21:00 ` [PATCH i-g-t 0/3] Convert sh scripts to C variants Jani Nikula
2016-10-21  7:38   ` Joonas Lahtinen
2016-10-24  8:46     ` Daniel Vetter
2016-10-24  8:49       ` Daniel Vetter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20161024084037.GG20761@phenom.ffwll.local \
    --to=daniel@ffwll.ch \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=marius.c.vlad@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.