1. In the Linux kernel, the production will see the call to align Align, common such as page alignment in memory management, Net_device, the acquisition of private data, this article is a simple analysis of align macros.
1.1. Kernel call: In E100.C, the NIC IRQ handler function irqreturn_t e100_intr (int irq, void *dev_id) calls the Netdev_priv (Netdev) handler to get the Net_device private data.
2105 static irqreturn_t e100_intr (int irq, void *dev_id)
2106 {
2107 struct Net_device *netdev = dev_id;
2108 struct nic *nic = Netdev_priv (Netdev);
The Netdev_priv function and the Align macro are defined as follows:
991 static inline void *netdev_priv (const struct Net_device *dev)
992 {
993 return (char *) dev + ALIGN (sizeof (struct net_device), netdev_align);
994}
#define ALIGN (X,a) __align_mask (x, (typeof (X)) (a)-1)
__align_mask #define (X,mask) (((x) + (mask)) &~ (mask))
1.2 Usage Analysis:
First of all, the use of ALIGN, ALIGN (X,a) is to align X with a as a boundary, the principle is to give X a minimum number, so that X is a boundary alignment. For example, a = 8, x=0, ALIGN (x,a) evaluates to 0, a = 8, x = 3, the result of the operation is 8, a = 8, x = 11, and the result of the operation is 16.
1.3 Principle Analysis:
For ease of analysis, it is assumed that the numbers used are 16bit,typeof, which can be ignored when the type definition is analyzed, assuming that X is aligned in 8-bit bounds.
A = 8, then the above mask= 7, then __align_mask (X,mask) ((((x) + (mask)) &~ (mask) is represented by binary:
X xxxx xxxx
MASK + 0000 0111
Further, the above formula can be divided into X low three bits all 0 (add mask after no carry) and low three bits are not all 0 (add mask after carry) two cases.
1.3.1. x low three bits are all 0 (add mask no carry)
That is, x = xxxx x000, in which case the __align_mask (x,mask) operation result is still x, and x itself is a multiple of 8, so X is bounded by 8.
1.3.2 x low three bit not all 0 (plus mask with rounding)
X + mask can be understood to give X plus 7 so that x to the fourth low, while the low three-bit zeroing, after the operation x = xxxx x000, the same as a multiple of 8, so X is bounded by 8.
Align parsing in the Linux kernel