Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 4 Jun 2005 23:51:20 -0400
From:      Garance A Drosihn <drosih@rpi.edu>
To:        freebsd-arch@FreeBSD.ORG
Subject:   NOTE: Upcoming changes to kinfo_proc
Message-ID:  <p0621022fbec81aa35c42@[128.113.24.47]>

next in thread | raw e-mail | index | archive | help
With the code-freeze for major changes to the 6.x-current branch
approaching rapidly, there's some changes that I plan to make to
'struct kinfo_proc' in sys/sys/user.h.  This is the structure used
to communicate process-specific info between the kernel and commands
like 'ps', 'top', and 'w'.

All I want to do is fix some lost-space problems which came up due
to mistakes adding variables with MD-types (long, pointers).  I can
only do that by changing the size of the struct, and as long as I'm
doing that I am also going to add more spare room for future changes.
I have tried to minimize the disruption in the change, but when I
commit it people are going to have to recompile the entire base system
(and possibly a few ports?) the next time they compile a kernel.

My intent is to commit a change to kinfo_proc before next Friday,
June 10th.  The change I have right now is minimally-disruptive, but
I might go for a more disruptive change (one which moves more fields
around) if that seems like a better idea.

As long as I'm doing that, does anyone else have some fields they
were planning to add to kinfo_proc?  I'm particularly interested
in anything which might be an oddball type, since the struct will
already have spare room for char's, int's, long's, and pointers.

Right now my planned change looks like:

Index: user.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/user.h,v
retrieving revision 1.65
diff -u -r1.65 user.h
--- user.h	20 Mar 2005 10:35:22 -0000	1.65
+++ user.h	5 Jun 2005 03:44:35 -0000
@@ -60,48 +60,48 @@
  /*
   * KERN_PROC subtype ops return arrays of selected proc structure entries:
   *
- * When adding new fields to this structure, ALWAYS add them at the end
- * and decrease the size of the spare field by the amount of space that
- * you are adding.  Byte aligned data should be added to the ki_sparestring
- * space; other entries should be added to the ki_spare space. Always
- * verify that sizeof(struct kinfo_proc) == KINFO_PROC_SIZE when you are
- * done. If you change the size of this structure, many programs will stop
- * working! Once you have added the new field, you will need to add code
- * to initialize it in two places: kern/kern_proc.c in the function
- * fill_kinfo_proc and in lib/libkvm/kvm_proc.c in the function kvm_proclist.
+ * This struct includes several arrays of spare space, with different arrays
+ * for different standard C-types.  When adding new variables to this struct,
+ * the space for byte-aligned data should be taken from the ki_sparestring,
+ * pointers from ki_spareptrs, word-aligned data from ki_spareints, and
+ * doubleword-aligned data from ki_sparelongs.  Make sure the space for new
+ * variables come from the array which matches the size and alignment of
+ * those variables on ALL hardware platforms, and then adjust the appropriate
+ * KI_NSPARE_* value(s) to match.
   *
- * KI_NSPARE is the number of spare-longs to define in the array at the
- * end of kinfo_proc.  It may need to be overridden on a platform-specific
- * basis as new fields are added.
+ * Always verify that sizeof(struct kinfo_proc) == KINFO_PROC_SIZE on all
+ * platforms after you have added new variables.  If you change the value
+ * of KINFO_PROC_SIZE, then many userland programs will stop working until
+ * they are recompiled!
+ *
+ * Once you have added the new field, you will need to add code to initialize
+ * it in two places: kern/kern_proc.c in the function fill_kinfo_proc and
+ * in lib/libkvm/kvm_proc.c in the function kvm_proclist.
   */
-#define	KI_NSPARE	15
+#define	KI_NSPARE_INT	14
+#define	KI_NSPARE_LONG	15
+#define	KI_NSPARE_PTR	7

  #ifdef __alpha__
-#define	KINFO_PROC_SIZE	912
+#define	KINFO_PROC_SIZE	1024
  #endif
  #ifdef __amd64__
-#define	KINFO_PROC_SIZE	912
+#define	KINFO_PROC_SIZE	1024		/* value has not been 
tested... */
  #endif
  #ifdef __arm__
-#undef KI_NSPARE			/* Fewer spare longs on this arch */
-#define	KI_NSPARE	13
-#define	KINFO_PROC_SIZE	648
+#define	KINFO_PROC_SIZE	740		/* value has not been 
tested... */
  #endif
  #ifdef __ia64__
-#define	KINFO_PROC_SIZE 912
+#define	KINFO_PROC_SIZE 1024
  #endif
  #ifdef __i386__
-#undef KI_NSPARE			/* Fewer spare longs on this arch */
-#define	KI_NSPARE	13
-#define	KINFO_PROC_SIZE	648
+#define	KINFO_PROC_SIZE	740
  #endif
  #ifdef __powerpc__
-#undef KI_NSPARE			/* Fewer spare longs on this arch */
-#define	KI_NSPARE	14
-#define	KINFO_PROC_SIZE	656
+#define	KINFO_PROC_SIZE	744
  #endif
  #ifdef __sparc64__
-#define	KINFO_PROC_SIZE 912
+#define	KINFO_PROC_SIZE 1024
  #endif
  #ifndef KINFO_PROC_SIZE
  #error "Unknown architecture"
@@ -180,7 +180,7 @@
  	char	ki_sparestrings[68];	/* spare string space */
  	struct	rusage ki_rusage;	/* process rusage statistics */
  	long	ki_sflag;		/* PS_* flags */
-	struct	priority ki_pri;	/* process priority */
+	long	ki_spare_long1;		/* unused (old location for ki_pri) */
  	long	ki_tdflags;		/* XXXKSE kthread flag */
  	struct	pcb *ki_pcb;		/* kernel virtual addr of pcb */
  	void	*ki_kstack;		/* kernel virtual addr of stack */
@@ -189,9 +189,16 @@
  	lwpid_t	ki_tid;			/* XXXKSE thread id */
  	int	ki_numthreads;		/* XXXKSE number of threads in total */
  	void	*ki_udata;		/* User convenience pointer */
+	void	*ki_spareptrs[KI_NSPARE_PTR];	/* spare room for growth */
+	struct	priority ki_pri;	/* process priority */
  	int	ki_jid;			/* Process jail ID */
-	int	ki_spare_int1;		/* unused (just here for alignment) */
-	long	ki_spare[KI_NSPARE];	/* spare room for later growth */
+	/*
+	 * When adding new variables, put new int's in front of ki_spareints,
+	 * and new longs at the end of ki_sparelongs.  That way the spare
+	 * room of both arrays will remain a contiguous area.
+	 */
+	int	ki_spareints[KI_NSPARE_INT];	/* spare room for growth */
+	long	ki_sparelongs[KI_NSPARE_LONG];	/* spare room for growth */
  };
  void fill_kinfo_proc(struct proc *, struct kinfo_proc *);



-- 
Garance Alistair Drosehn            =   gad@gilead.netel.rpi.edu
Senior Systems Programmer           or  gad@freebsd.org
Rensselaer Polytechnic Institute    or  drosih@rpi.edu



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?p0621022fbec81aa35c42>