[Intel-gfx] [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.

Daniel Vetter daniel at ffwll.ch
Mon Oct 24 08:40:37 UTC 2016


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 at 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 at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


More information about the Intel-gfx mailing list