On Mon, Oct 24, 2016 at 10:40:37AM +0200, Daniel Vetter wrote:
> 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 <[email protected]>
> > ---
> >  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 ;-)
Have no issue putting kmod helpers into their own file. Can't really
tell which is the best approach though: the only user is drv_module_reload
yet the test already got ``fatten'' up with the gem subtests (see v3).
> 
> 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).
Sorry, I totally missed your input, will double check on this.
> -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
> > [email protected]
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

Attachment: signature.asc
Description: PGP signature

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to