(root)/
strace-6.5/
src/
numa.c
       1  /*
       2   * Copyright (c) 2003-2007 Ulrich Drepper <drepper@redhat.com>
       3   * Copyright (c) 2005-2016 Dmitry V. Levin <ldv@strace.io>
       4   * Copyright (c) 2016-2022 The strace developers.
       5   * All rights reserved.
       6   *
       7   * SPDX-License-Identifier: LGPL-2.1-or-later
       8   */
       9  
      10  #include "defs.h"
      11  
      12  static bool
      13  print_node(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
      14  {
      15  	if (elem_size < sizeof(kernel_ulong_t)) {
      16  		unsigned int val = *(unsigned int *) elem_buf;
      17  		PRINT_VAL_0X(val);
      18  	} else {
      19  		kernel_ulong_t val = *(kernel_ulong_t *) elem_buf;
      20  		PRINT_VAL_0X(val);
      21  	}
      22  
      23  	return true;
      24  }
      25  
      26  static void
      27  print_nodemask(struct tcb *const tcp, const kernel_ulong_t addr,
      28  	       const kernel_ulong_t maxnodes)
      29  {
      30  	const unsigned int bits_per_long = 8 * current_wordsize;
      31  	const kernel_ulong_t nmemb =
      32  		(maxnodes + bits_per_long - 2) / bits_per_long;
      33  
      34  	if (nmemb < maxnodes / bits_per_long ||
      35  	    (maxnodes && !nmemb)) {
      36  		printaddr(addr);
      37  		return;
      38  	}
      39  
      40  	kernel_ulong_t buf;
      41  	print_array(tcp, addr, nmemb, &buf, current_wordsize,
      42  		    tfetch_mem, print_node, 0);
      43  }
      44  
      45  SYS_FUNC(migrate_pages)
      46  {
      47  	/* pid */
      48  	printpid(tcp, tcp->u_arg[0], PT_TGID);
      49  	tprint_arg_next();
      50  
      51  	/* maxnode */
      52  	PRINT_VAL_U(tcp->u_arg[1]);
      53  	tprint_arg_next();
      54  
      55  	/* old_nodes */
      56  	print_nodemask(tcp, tcp->u_arg[2], tcp->u_arg[1]);
      57  	tprint_arg_next();
      58  
      59  	/* new_nodes */
      60  	print_nodemask(tcp, tcp->u_arg[3], tcp->u_arg[1]);
      61  
      62  	return RVAL_DECODED;
      63  }
      64  
      65  #include "xlat/mpol_modes.h"
      66  #include "xlat/mpol_mode_flags.h"
      67  #include "xlat/mbind_flags.h"
      68  
      69  static void
      70  print_mode(struct tcb *const tcp, const kernel_ulong_t mode_arg)
      71  {
      72  	const kernel_ulong_t flags_mask = MPOL_F_STATIC_NODES |
      73  					  MPOL_F_RELATIVE_NODES |
      74  					  MPOL_F_NUMA_BALANCING;
      75  	const kernel_ulong_t mode = mode_arg & ~flags_mask;
      76  	const unsigned int flags = mode_arg & flags_mask;
      77  
      78  	if (!flags) {
      79  		printxval64(mpol_modes, mode, "MPOL_???");
      80  		return;
      81  	}
      82  
      83  	const char *mode_str = xlookup(mpol_modes, mode);
      84  	if (!mode_str) {
      85  		printflags64(mpol_mode_flags, mode_arg, "MPOL_???");
      86  		return;
      87  	}
      88  
      89  	if (xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV)
      90  		PRINT_VAL_X(mode_arg);
      91  
      92  	if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)
      93  		return;
      94  
      95  	if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
      96  		tprint_comment_begin();
      97  
      98  	tprint_flags_begin();
      99  	tprints_string(mode_str);
     100  	tprint_flags_or();
     101  	printflags_ex(flags, NULL, XLAT_STYLE_ABBREV, mpol_mode_flags, NULL);
     102  	tprint_flags_end();
     103  
     104  	if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
     105  		tprint_comment_end();
     106  }
     107  
     108  SYS_FUNC(mbind)
     109  {
     110  	/* addr */
     111  	printaddr(tcp->u_arg[0]);
     112  	tprint_arg_next();
     113  
     114  	/* len */
     115  	PRINT_VAL_U(tcp->u_arg[1]);
     116  	tprint_arg_next();
     117  
     118  	/* mode */
     119  	print_mode(tcp, tcp->u_arg[2]);
     120  	tprint_arg_next();
     121  
     122  	/* nodemask */
     123  	print_nodemask(tcp, tcp->u_arg[3], tcp->u_arg[4]);
     124  	tprint_arg_next();
     125  
     126  	/* maxnode */
     127  	PRINT_VAL_U(tcp->u_arg[4]);
     128  	tprint_arg_next();
     129  
     130  	/* flags */
     131  	printflags(mbind_flags, tcp->u_arg[5], "MPOL_???");
     132  
     133  	return RVAL_DECODED;
     134  }
     135  
     136  SYS_FUNC(set_mempolicy)
     137  {
     138  	/* mode */
     139  	print_mode(tcp, (unsigned int) tcp->u_arg[0]);
     140  	tprint_arg_next();
     141  
     142  	/* nodemask */
     143  	print_nodemask(tcp, tcp->u_arg[1], tcp->u_arg[2]);
     144  	tprint_arg_next();
     145  
     146  	/* maxnode */
     147  	PRINT_VAL_U(tcp->u_arg[2]);
     148  
     149  	return RVAL_DECODED;
     150  }
     151  
     152  #include "xlat/get_mempolicy_flags.h"
     153  
     154  SYS_FUNC(get_mempolicy)
     155  {
     156  	if (exiting(tcp)) {
     157  		/* mode */
     158  		int pol;
     159  		if (!umove_or_printaddr(tcp, tcp->u_arg[0], &pol)) {
     160  			tprint_indirect_begin();
     161  			printxval(mpol_modes, pol, "MPOL_???");
     162  			tprint_indirect_end();
     163  		}
     164  		tprint_arg_next();
     165  
     166  		/* nodemask */
     167  		print_nodemask(tcp, tcp->u_arg[1], tcp->u_arg[2]);
     168  		tprint_arg_next();
     169  
     170  		/* maxnode */
     171  		PRINT_VAL_U(tcp->u_arg[2]);
     172  		tprint_arg_next();
     173  
     174  		/* addr */
     175  		printaddr(tcp->u_arg[3]);
     176  		tprint_arg_next();
     177  
     178  		/* flags */
     179  		printflags64(get_mempolicy_flags, tcp->u_arg[4], "MPOL_???");
     180  	}
     181  	return 0;
     182  }
     183  
     184  SYS_FUNC(set_mempolicy_home_node)
     185  {
     186  	/* start */
     187  	printaddr(tcp->u_arg[0]);
     188  	tprint_arg_next();
     189  
     190  	/* len */
     191  	PRINT_VAL_U(tcp->u_arg[1]);
     192  	tprint_arg_next();
     193  
     194  	/* home_node */
     195  	PRINT_VAL_U(tcp->u_arg[2]);
     196  	tprint_arg_next();
     197  
     198  	/* flags */
     199  	PRINT_VAL_X(tcp->u_arg[3]);
     200  
     201  	return RVAL_DECODED;
     202  }
     203  
     204  #include "xlat/move_pages_flags.h"
     205  
     206  static bool
     207  print_addr(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
     208  {
     209  	kernel_ulong_t addr;
     210  
     211  	if (elem_size < sizeof(addr)) {
     212  		addr = *(unsigned int *) elem_buf;
     213  	} else {
     214  		addr = *(kernel_ulong_t *) elem_buf;
     215  	}
     216  
     217  	printaddr(addr);
     218  
     219  	return true;
     220  }
     221  
     222  static bool
     223  print_status(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
     224  {
     225  	const int status = *(int *) elem_buf;
     226  
     227  	print_err(status, true);
     228  
     229  	return true;
     230  }
     231  
     232  SYS_FUNC(move_pages)
     233  {
     234  	const kernel_ulong_t npages = tcp->u_arg[1];
     235  	kernel_ulong_t buf;
     236  
     237  	if (entering(tcp)) {
     238  		/* pid */
     239  		printpid(tcp, tcp->u_arg[0], PT_TGID);
     240  		tprint_arg_next();
     241  
     242  		/* count */
     243  		PRINT_VAL_U(npages);
     244  		tprint_arg_next();
     245  
     246  		/* pages */
     247  		print_array(tcp, tcp->u_arg[2], npages, &buf, current_wordsize,
     248  			    tfetch_mem, print_addr, 0);
     249  		tprint_arg_next();
     250  
     251  		/* nodes */
     252  		print_array(tcp, tcp->u_arg[3], npages, &buf, sizeof(int),
     253  			    tfetch_mem, print_int_array_member, 0);
     254  		tprint_arg_next();
     255  	} else {
     256  		/* status */
     257  		print_array(tcp, tcp->u_arg[4], npages, &buf, sizeof(int),
     258  			    tfetch_mem, print_status, 0);
     259  		tprint_arg_next();
     260  
     261  		/* flags */
     262  		printflags(move_pages_flags, tcp->u_arg[5], "MPOL_???");
     263  	}
     264  	return 0;
     265  }