Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package powerpc-utils for openSUSE:Factory 
checked in at 2021-09-07 21:13:44
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/powerpc-utils (Old)
 and      /work/SRC/openSUSE:Factory/.powerpc-utils.new.1899 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "powerpc-utils"

Tue Sep  7 21:13:44 2021 rev:118 rq:916775 version:1.3.9

Changes:
--------
--- /work/SRC/openSUSE:Factory/powerpc-utils/powerpc-utils.changes      
2021-08-25 20:57:34.729210769 +0200
+++ /work/SRC/openSUSE:Factory/.powerpc-utils.new.1899/powerpc-utils.changes    
2021-09-07 21:13:53.232756578 +0200
@@ -1,0 +2,6 @@
+Fri Sep  3 18:04:46 UTC 2021 - Michal Suchanek <msucha...@suse.de>
+
+- Optimize lsdevinfo filtering to prevent LPM timeouts (bsc#1189571 
LTC#193419).
+  + lsdevinfo-optimize-criteria-filtering.patch
+
+-------------------------------------------------------------------

New:
----
  lsdevinfo-optimize-criteria-filtering.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ powerpc-utils.spec ++++++
--- /var/tmp/diff_new_pack.SL1GPP/_old  2021-09-07 21:13:53.644757075 +0200
+++ /var/tmp/diff_new_pack.SL1GPP/_new  2021-09-07 21:13:53.644757075 +0200
@@ -28,6 +28,7 @@
 Patch1:         powerpc-utils-lsprop.patch
 Patch2:         ofpathname_powernv.patch
 Patch4:         libvirt-service-dep.patch
+Patch5:         lsdevinfo-optimize-criteria-filtering.patch
 Patch14:        fix_kexec_service_name_for_suse.patch
 BuildRequires:  autoconf
 BuildRequires:  automake

++++++ lsdevinfo-optimize-criteria-filtering.patch ++++++
>From 51b50ec77451fb9164d6379bfe3ab9ade8a672c5 Mon Sep 17 00:00:00 2001
From: Scott Cheloha <chel...@linux.ibm.com>
Date: Tue, 27 Jul 2021 11:30:58 -0500
Subject: [PATCH] lsdevinfo: optimize criteria filtering

lsdevinfo is significantly slower when a criteria filter is set with the
-q flag.

There are two culprits:

1. The criteria string given on the command line is parsed every time
   we call check_criteria().  We're forking two sed(1) processes whenever
   we hit that function.  We hit it a lot.

2. Criteria checking runs in constant time.  We call check_criteria() and
   do the parsing in (1) for every relevant attribute, even if we already
   have a match from a prior check_criteria() invocation.

We can fix issue (1) by parsing the criteria string once at the start
of the script.  I have added a function, parse_criteria(), that parses
the $criteria string and selects an appropriate matching function.

This approach also fixes problem (2), but we first need to check
whether the user's criteria is relevant to the attributes the script
cares about before calling the matching function.  We do this with
criteria_is_relevant().

The speed improvement is nice.  Consider my test machine with around
thirty devices.  On this machine, lsdevinfo without any options runs
in 1.35s, but with the "status=1" criteria it runs in 2.12s:

$ /usr/sbin/lsdevinfo | fgrep -c device:
29
$ command time -p /usr/sbin/lsdevinfo > /dev/null
real 1.35
user 1.42
sys 0.16
$ command time -p /usr/sbin/lsdevinfo -q status=1 > /dev/null
real 2.12
user 2.22
sys 0.30

With this patch, lsdevinfo with the "status=1" criteria now runs in
1.35s:

$ command time -p /usr/sbin/lsdevinfo -q status=1 > /dev/null
real 1.35
user 1.41
sys 0.18

This patch eliminates nearly all of the criteria-checking overhead in
the current code.

Signed-off-by: Scott Cheloha <chel...@linux.ibm.com>
---
 scripts/lsdevinfo | 197 ++++++++++++++++++++++++++++++----------------
 1 file changed, 129 insertions(+), 68 deletions(-)

diff --git a/scripts/lsdevinfo b/scripts/lsdevinfo
index 1d9597bc4bc9..7a3cba3bee9f 100755
--- a/scripts/lsdevinfo
+++ b/scripts/lsdevinfo
@@ -61,37 +61,113 @@ show_version()
     echo "Written by: Santiago Leon <sl...@ec.ibm.com>"
 }
 
-# check_criteria
-# Modifies $show if the the attribute in the first parameter matches the
-# criteria from the command line.
-# The operands (=, !=, and LIKE) are defined the the lsdevinfo spec.
 #
-check_criteria()
+# Criteria matching boilerplate.
+#
+_class_eq() { [[ $class = $crit_rhs ]]; }
+_class_neq() { [[ $class != $crit_rhs ]]; }
+_class_like() { [[ $class =~ $crit_rhs ]]; }
+
+_driver_eq() { [[ $driver = $crit_rhs ]]; }
+_driver_neq() { [[ $driver != $crit_rhs ]]; }
+_driver_like() { [[ $driver =~ $crit_rhs ]]; }
+
+_name_eq() { [[ $name = $crit_rhs ]]; }
+_name_neq() { [[ $name != $crit_rhs ]]; }
+_name_like() { [[ $name =~ $crit_rhs ]]; }
+
+_parent_eq() { [[ $parent = $crit_rhs ]]; }
+_parent_neq() { [[ $parent != $crit_rhs ]]; }
+_parent_like() { [[ $parent =~ $crit_rhs ]]; }
+
+_physloc_eq() { [[ $physloc = $crit_rhs ]]; }
+_physloc_neq() { [[ $physloc != $crit_rhs ]]; }
+_physloc_like() { [[ $physloc =~ $crit_rhs ]]; }
+
+_prefix_eq() { [[ $prefix = $crit_rhs ]]; }
+_prefix_neq() { [[ $prefix != $crit_rhs ]]; }
+_prefix_like() { [[ $prefix =~ $crit_rhs ]]; }
+
+_status_eq() { [[ $status = $crit_rhs ]]; }
+_status_neq() { [[ $status != $crit_rhs ]]; }
+_status_like() { [[ $status =~ $crit_rhs ]]; }
+
+_subclass_eq() { [[ $subclass = $crit_rhs ]]; }
+_subclass_neq() { [[ $subclass != $crit_rhs ]]; }
+_subclass_like() { [[ $subclass =~ $crit_rhs ]]; }
+
+_type_eq() { [[ $type = $crit_rhs ]]; }
+_type_neq() { [[ $type != $crit_rhs ]]; }
+_type_like() { [[ $type =~ $crit_rhs ]]; }
+
+_uniquetype_eq() { [[ $uniquetype = $crit_rhs ]]; }
+_uniquetype_neq() { [[ $uniquetype != $crit_rhs ]]; }
+_uniquetype_like() { [[ $uniquetype =~ $crit_rhs ]]; }
+
+# Check if the attribute we're filtering on appears in the string
+# given as argument.
+criteria_is_relevant()
 {
-    attr=$1
-    attr_val=${!attr}
+    [[ "$1" =~ "$crit_lhs" ]]
+}
 
+# Run the criteria-matching function.
+criteria_matches()
+{
+    $criteria_checker
+}
+
+# Select a criteria-matching function based on the $criteria string.
+parse_criteria()
+{
     if [[ $criteria =~ "!=" ]] ; then
-       # Pull out the operands from the criteria (everything to the left of 
-       # the operand, and everything on the right of the operand)
-        crit_opd1=$(echo $criteria | $SED -e "s/[ ]*!=.*//")
-        crit_opd2=$(echo $criteria | $SED -e "s/.*!=[ ]*//")
-       # Perfom the comparison of the attribute and its value
-        if [[ $crit_opd1 == $attr && $crit_opd2 != $attr_val ]]; then
-           show=1
-       fi
+        crit_lhs=$(echo $criteria | $SED -e "s/[ ]*!=.*//")
+        crit_rhs=$(echo $criteria | $SED -e "s/.*!=[ ]*//")
+       case "$crit_lhs" in
+           class) criteria_checker=_class_neq;;
+           driver) criteria_checker=_driver_neq;;
+           name) criteria_checker=_name_neq;;
+           parent) criteria_checker=_parent_neq;;
+           physloc) criteria_checker=_physloc_neq;;
+           prefix) criteria_checker=_prefix_neq;;
+           status) criteria_checker=_status_neq;;
+           subclass) criteria_checker=_subclass_neq;;
+           type) criteria_checker=_type_neq;;
+           uniquetype) criteria_checker=_uniquetype_neq;;
+           *) criteria_checker=false;;
+       esac
     elif [[ $criteria =~ "=" ]]; then
-        crit_opd1=$(echo $criteria | $SED -e "s/[ ]*=.*//")
-        crit_opd2=$(echo $criteria | $SED -e "s/.*=[ ]*//")
-       if [[ $crit_opd1 == $attr && $crit_opd2 == $attr_val ]]; then
-           show=1
-       fi
+        crit_lhs=$(echo $criteria | $SED -e "s/[ ]*=.*//")
+        crit_rhs=$(echo $criteria | $SED -e "s/.*=[ ]*//")
+       case "$crit_lhs" in
+           class) criteria_checker=_class_eq;;
+           driver) criteria_checker=_driver_eq;;
+           name) criteria_checker=_name_eq;;
+           parent) criteria_checker=_parent_eq;;
+           physloc) criteria_checker=_physloc_eq;;
+           prefix) criteria_checker=_prefix_eq;;
+           status) criteria_checker=_status_eq;;
+           subclass) criteria_checker=_subclass_eq;;
+           type) criteria_checker=_type_eq;;
+           uniquetype) criteria_checker=_uniquetype_eq;;
+           *) criteria_checker=false;;
+       esac
     elif [[ $criteria =~ " LIKE " ]]; then
-        crit_opd1=$(echo $criteria | $SED -e "s/[ ]*LIKE.*//")
-        crit_opd2=$(echo $criteria | $SED -e "s/.*LIKE[ ]*//")
-       if [[ $crit_opd1 == $attr && $attr_val =~ $crit_opd2 ]]; then
-           show=1
-       fi
+        crit_lhs=$(echo $criteria | $SED -e "s/[ ]*LIKE.*//")
+        crit_rhs=$(echo $criteria | $SED -e "s/.*LIKE[ ]*//")
+       case "$crit_lhs" in
+           class) criteria_checker=_class_like;;
+           driver) criteria_checker=_driver_like;;
+           name) criteria_checker=_name_like;;
+           parent) criteria_checker=_parent_like;;
+           physloc) criteria_checker=_physloc_like;;
+           prefix) criteria_checker=_prefix_like;;
+           status) criteria_checker=_status_like;;
+           subclass) criteria_checker=_subclass_like;;
+           type) criteria_checker=_type_like;;
+           uniquetype) criteria_checker=_uniquetype_like;;
+           *) criteria_checker=false;;
+       esac
     else
         echo "Criteria must have =, !=, or LIKE operand. Exiting."
         exit 1
@@ -124,6 +200,8 @@ recursive=0
 
 # default: display all devices
 criteria=""
+criteria_checker=:
+crit_lhs=""
 
 # default: display all attributes
 format=""
@@ -162,6 +240,12 @@ if [[ $criteria =~ " AND " ]] ; then
     exit 1
 fi
 
+# If we have a criteria string, parse it and choose a criteria
+# matching function.
+if [[ -n "$criteria" ]]; then
+    parse_criteria
+fi
+
 # Fill variables for the two display formats (regular and comma-separated) so
 # we can print the output in a single place.
 if [[ $comma_sep -eq 0 ]]; then
@@ -184,15 +268,10 @@ show_eth ()
     # if there is a criteria in the command line, check if this device matches
     if [[ $criteria != "" ]] ; then
         show=0
-        check_criteria "name"
-        check_criteria "physloc"
-        check_criteria "uniquetype"
-        check_criteria "class"
-        check_criteria "subclass"
-        check_criteria "type"
-        check_criteria "prefix"
-        check_criteria "driver"
-        check_criteria "status"
+        attrs="name physloc uniquetype class subclass type prefix driver 
status"
+        if criteria_is_relevant "$attrs" && criteria_matches; then
+            show=1
+        fi
     fi
 
     # print the info only if the device matches the criteria
@@ -330,15 +409,10 @@ for dev in $($LS -d /proc/device-tree/vdevice/v-scsi* 2> 
/dev/null) ; do
        # device matches
        if [[ $criteria != "" ]] ; then
            show=0
-           check_criteria "name"
-           check_criteria "physloc"
-           check_criteria "status"
-           check_criteria "uniquetype"
-           check_criteria "class"
-           check_criteria "subclass"
-           check_criteria "type"
-           check_criteria "prefix"
-           check_criteria "driver"
+           attrs="name physloc status uniquetype class subclass type prefix 
driver"
+           if criteria_is_relevant "$attrs" && criteria_matches; then
+               show=1
+           fi
        fi
 
        if [[ $show -ne 0 ]]; then
@@ -395,14 +469,10 @@ for dev in $($LS -d /proc/device-tree/vdevice/v-scsi* 2> 
/dev/null) ; do
                # if there is a criteria in the command line, check if this
                # device matches
                show=0
-               check_criteria "name"
-               check_criteria "status"
-               check_criteria "physloc"
-               check_criteria "parent"
-               check_criteria "uniquetype"
-               check_criteria "class"
-               check_criteria "subclass"
-               check_criteria "type"
+               attrs="name status physloc parent uniquetype class subclass 
type"
+               if criteria_is_relevant "$attrs" && criteria_matches; then
+                   show=1
+               fi
            else
                show=1
            fi
@@ -475,15 +545,10 @@ for dev in $($LS -d /proc/device-tree/vdevice/vfc-client* 
2> /dev/null) ; do
        # device matches
        if [[ $criteria != "" ]] ; then
            show=0
-           check_criteria "name"
-           check_criteria "physloc"
-           check_criteria "status"
-           check_criteria "uniquetype"
-           check_criteria "class"
-           check_criteria "subclass"
-           check_criteria "type"
-           check_criteria "prefix"
-           check_criteria "driver"
+           attrs="name physloc status uniquetype class subclass type prefix 
driver"
+           if criteria_is_relevant "$attrs" && criteria_matches; then
+               show=1
+           fi
        fi
 
        if [[ $show -ne 0 ]]; then
@@ -543,14 +608,10 @@ for dev in $($LS -d /proc/device-tree/vdevice/vfc-client* 
2> /dev/null) ; do
                    # if there is a criteria in the command line, check if this
                    # device matches
                         show=0
-                       check_criteria "name"
-                       check_criteria "physloc"
-                       check_criteria "status"
-                       check_criteria "parent"
-                       check_criteria "uniquetype"
-                       check_criteria "class"
-                       check_criteria "subclass"
-                       check_criteria "type"
+                       attrs="name physloc status parent uniquetype class 
subclass type"
+                       if criteria_is_relevant "$attrs" && criteria_matches; 
then
+                           show=1
+                       fi
                    else
                         show=1
                    fi
-- 
2.31.1

Reply via email to